কোনও সেট সদস্য হিসাবে 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;
}
}