কোনও সেট সদস্য হিসাবে System.Collections.Generic.HashSet<>
গ্রহণের null
মতো সংগ্রহগুলি দেওয়া, যে কেউ হ্যাশ কোডটি কী null
হতে হবে তা জিজ্ঞাসা করতে পারে। ফ্রেমওয়ার্কটি ব্যবহার করে বলে মনে হচ্ছে 0
:
// nullable struct type
int? i = null;
i.GetHashCode(); // gives 0
EqualityComparer<int?>.Default.GetHashCode(i); // gives 0
// class type
CultureInfo c = null;
EqualityComparer<CultureInfo>.Default.GetHashCode(c); // gives 0
এটি (সামান্য) নালাগুলি এনামগুলিতে সমস্যাযুক্ত হতে পারে। যদি আমরা সংজ্ঞায়িত করি
enum Season
{
Spring,
Summer,
Autumn,
Winter,
}
তারপরে Nullable<Season>
(এটিও বলা হয় Season?
) মাত্র পাঁচটি মান নিতে পারে তবে এর মধ্যে দুটি, যথা null
এবং Season.Spring
, একই হ্যাশ কোড থাকতে পারে।
এটি এইরকম একটি "আরও ভাল" সমতা তুলনামূলক লিখতে লোভনীয়:
class NewNullEnumEqComp<T> : EqualityComparer<T?> where T : struct
{
public override bool Equals(T? x, T? y)
{
return Default.Equals(x, y);
}
public override int GetHashCode(T? x)
{
return x.HasValue ? Default.GetHashCode(x) : -1;
}
}
তবে হ্যাশ কোডটি হওয়ার কোনও কারণ আছে null
কি 0
?
সম্পাদনা / সংস্থান:
কিছু লোক মনে করে এটি ওভাররাইডিং সম্পর্কে Object.GetHashCode()
। আসলেই তা হয় না। (.NET লেখক একটি ওভাররাইড করতে করেনি GetHashCode()
মধ্যে Nullable<>
struct যা হয় যদিও প্রাসঙ্গিক,।) Parameterless একজন ব্যবহারকারী লেখা বাস্তবায়ন GetHashCode()
পরিস্থিতি কখনোই সব ব্যবস্থা করতে সক্ষম যেখানে অবজেক্ট যার হ্যাশ কোড আমরা চাইতে হয় null
।
এটি বিমূর্ত পদ্ধতিটি EqualityComparer<T>.GetHashCode(T)
প্রয়োগ করা বা অন্যথায় ইন্টারফেস পদ্ধতিটি বাস্তবায়নের বিষয়ে IEqualityComparer<T>.GetHashCode(T)
। এখন, এমএসডিএন-এ এই লিঙ্কগুলি তৈরি করার সময়, আমি দেখতে পাচ্ছি যে এটি সেখানে বলেছে যে ArgumentNullException
যদি তাদের একক যুক্তি হয় তবে এই পদ্ধতিগুলি একটি ছুঁড়ে ফেলে null
। এমএসডিএন এ নিশ্চয়ই ভুল হতে পারে? .NET এর নিজস্ব প্রয়োগসমূহ কোনওটিই ব্যতিক্রম ছুঁড়ে না ফেলে। যে ক্ষেত্রে নিক্ষেপ কার্যকরভাবে যুক্ত করার জন্য কোন চেষ্টা বিরতি দেবে null
একটি থেকে HashSet<>
। HashSet<>
কোনও null
আইটেমের সাথে কাজ করার সময় অসাধারণ কিছু না করলে (আমাকে এটি পরীক্ষা করতে হবে)।
নতুন সম্পাদনা / সংস্থান:
এখন আমি ডিবাগ করার চেষ্টা করেছি। এর সাথে HashSet<>
, আমি নিশ্চিত করতে পারি যে ডিফল্ট সমতা তুলনামূলক, মানগুলি Season.Spring
এবং একই বালতিতে শেষ null
হবে । এটি খুব সতর্কতার সাথে ব্যক্তিগত অ্যারে সদস্যদের পরিদর্শন করে নির্ধারণ করা যেতে পারে m_buckets
এবং m_slots
। নোট করুন যে সূচকগুলি সর্বদা ডিজাইন অনুসারে একের পর এক অফসেট থাকে।
আমি উপরে যে কোডটি দিয়েছি তা এটি ঠিক করে না। দেখা যাচ্ছে যে, HashSet<>
মানটি কখনই সমতা তুলনামূলককে জিজ্ঞাসা করবে না null
। এটি এর উত্স কোড থেকে HashSet<>
:
// Workaround Comparers that throw ArgumentNullException for GetHashCode(null).
private int InternalGetHashCode(T item) {
if (item == null) {
return 0;
}
return m_comparer.GetHashCode(item) & Lower31BitMask;
}
এর অর্থ হ'ল, অন্ততপক্ষে HashSet<>
, এটির হ্যাশ পরিবর্তন করাও সম্ভব নয় null
। পরিবর্তে, একটি সমাধান হ'ল এইরকম অন্যান্য মানগুলির হ্যাশ পরিবর্তন করা:
class NewerNullEnumEqComp<T> : EqualityComparer<T?> where T : struct
{
public override bool Equals(T? x, T? y)
{
return Default.Equals(x, y);
}
public override int GetHashCode(T? x)
{
return x.HasValue ? 1 + Default.GetHashCode(x) : /* not seen by HashSet: */ 0;
}
}