नए शुरू किए गए रिकॉर्ड प्रकार EqualityContract को टाइप करने के लिए ओवरराइड करने की अनुमति देते हैं जो एक ऐसी स्थिति बनाना संभव बनाता है जब दो ऑब्जेक्ट समान होते हैं लेकिन अलग-अलग हैशकोड होते हैं जो दिशानिर्देश:

यदि आप GetHashCode विधि को ओवरराइड करते हैं, तो आपको बराबर ओवरराइड करना चाहिए, और इसके विपरीत। यदि दो वस्तुओं की समानता के लिए परीक्षण किए जाने पर आपकी ओवरराइड की गई समान विधि सही हो जाती है, तो आपकी ओवरराइड की गई GetHashCode विधि को दो वस्तुओं के लिए समान मान वापस करना होगा।

    public record Base(string Foo);

    public record Child(string Foo, string Bar) : Base(Foo)
    {
        protected override Type EqualityContract => typeof(Base);
    }

    var b = new Base("Foo");
    var c = new Child("Foo", "Bar");
    Console.WriteLine(b == c); // True
    Console.WriteLine(b.GetHashCode() == c.GetHashCode()); // False

Child से अतिरिक्त संपत्ति को हटाते समय GetHashCode और Equals "मिलान" हो जाता है।

स्पष्ट रूप से इसे ओवरराइड करने के साथ तय किया जा सकता है GetHashCode, लेकिन मुझे आश्चर्य है कि EqualityContract को ओवरराइड करने से स्वचालित रूप से GetHashCode रिटर्न वैल्यू "मिलान" Equals कार्यान्वयन क्यों नहीं होता है? या मैन्युअल GetHashCode ओवरराइड को छोड़कर इसे संभालने का कोई और तरीका है।

4
Guru Stron 16 नवम्बर 2020, 22:00

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि आप समानता सदस्य भाग में देख सकते हैं रिकॉर्ड प्रस्ताव का ,

GetHashCode() एक नियतात्मक फ़ंक्शन का int परिणाम देता है निम्नलिखित मूल्यों का संयोजन:

  • हर इंस्टेंस फ़ील्ड के लिए fieldN रिकॉर्ड प्रकार में जो इनहेरिट नहीं किया गया है, का मान System.Collections.Generic.EqualityComparer<TN>.Default.GetHashCode(fieldN) जहां TN फ़ील्ड प्रकार है, और

  • यदि कोई आधार रिकॉर्ड प्रकार है, तो आधार का मान। GetHashCode (); अन्यथा का मान System.Collections.Generic.EqualityComparer<System.Type>.Default.GetHashCode(EqualityContract).

तो, आपके उदाहरण में GetHashCode Base के लिए होगा

public override int GetHashCode()
{
    return EqualityComparer<Type>.Default.GetHashCode(EqualityContract) + EqualityComparer<string>.Default.GetHashCode(Foo);
}

और Child के लिए

public override int GetHashCode()
{
    return base.GetHashCode() + EqualityComparer<string>.Default.GetHashCode(Bar);
}

इनहेरिट किए गए रिकॉर्ड के लिए EqualityContract का उपयोग हैश कोड गणना के लिए नहीं किया जाता है। यदि कोई अतिरिक्त गुण Bar हटा दिया जाता है, तो Base से मान का उपयोग किया जाता है और आपको हैश मान समानता प्राप्त होगी। अतः, GetHashCode को ओवरराइड करने की आवश्यकता है।

यह व्यवहार भी उपयोग कर मनाया जाता है sharplab.io

1
Pavel Anikhouski 17 नवम्बर 2020, 16:41