GetHashCode ओवरराइड करना
समानता और हैशिंग में संगति रखें।
GetHashCode ओवरराइड करना, CoddyKit पर C# अकादमी का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह C# अकादमी सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। C# अकादमी पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
GetHashCode क्यों महत्वपूर्ण है
Dictionary और HashSet जैसे हैश-आधारित संग्रह तत्वों को खानों में बाँटने के लिए GetHashCode का उपयोग करते हैं। यदि आप Equals को अधिभारित करते हैं लेकिन GetHashCode को नहीं, तो ये संग्रह समान तत्वों को खोजने में विफल हो सकते हैं।
स्वर्णिम नियम
नियम सरल है: यदि दो ऑब्जेक्ट समान हैं, तो उन्हें एक ही हैश कोड लौटाना चाहिए। इसका उलटा आवश्यक नहीं है; अलग-अलग ऑब्जेक्ट एक ही हैश कोड साझा कर सकते हैं, जिसे टक्कर कहते हैं।
using System;
public struct Point
{
public int X, Y;
public Point(int x, int y) { X = x; Y = y; }
public override bool Equals(object obj) => obj is Point p && p.X == X && p.Y == Y;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var a = new Point(1, 2);
var b = new Point(1, 2);
Console.WriteLine(a.Equals(b));
Console.WriteLine(a.GetHashCode() == b.GetHashCode());
}
}HashCode.Combine का उपयोग करें
HashCode.Combine सहायक कई फ़ील्ड मानों को मिलाकर अच्छी तरह वितरित हैश बनाता है। GetHashCode लागू करने का यह अनुशंसित आधुनिक तरीका है।
using System;
public struct Color
{
public int R, G, B;
public Color(int r, int g, int b) { R = r; G = g; B = b; }
public override bool Equals(object obj) => obj is Color c && c.R == R && c.G == G && c.B == B;
public override int GetHashCode() => HashCode.Combine(R, G, B);
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Color(255, 0, 0).GetHashCode() == new Color(255, 0, 0).GetHashCode());
}
}समानता और हैश निर्धारण को साथ परिभाषित करें
हमेशा Equals और GetHashCode को एक साथ अधिभारित करें और दोनों में उन्हीं फ़ील्ड का उपयोग करें। अलग-अलग फ़ील्ड का उपयोग करने पर समान ऑब्जेक्ट अलग-अलग हैश उत्पन्न कर सकते हैं।
using System;
public class Book
{
public string Title;
public int Year;
public Book(string title, int year) { Title = title; Year = year; }
public override bool Equals(object obj)
=> obj is Book b && b.Title == Title && b.Year == Year;
public override int GetHashCode() => HashCode.Combine(Title, Year);
}
public class Program
{
public static void Main()
{
var a = new Book("C#", 2020);
var b = new Book("C#", 2020);
Console.WriteLine(a.GetHashCode() == b.GetHashCode());
}
}शब्दकोशों को इसकी आवश्यकता क्यों होती है
Dictionary पहले कुंजी का हैश बनाकर उसका खाना ढूँढ़ता है, फिर उसी खाने के भीतर Equals का उपयोग करता है। गलत हैश खोज को गलत खाने में भेज देता है और कुंजी कभी नहीं मिलती।
using System;
using System.Collections.Generic;
public struct Coord
{
public int X, Y;
public Coord(int x, int y) { X = x; Y = y; }
public override bool Equals(object obj) => obj is Coord c && c.X == X && c.Y == Y;
public override int GetHashCode() => HashCode.Combine(X, Y);
}
public class Program
{
public static void Main()
{
var map = new Dictionary<Coord, string> { [new Coord(2, 3)] = "hit" };
Console.WriteLine(map[new Coord(2, 3)]);
}
}अपरिवर्तनीय फ़ील्ड का हैश बनाना
जब कोई ऑब्जेक्ट हैश संग्रह में रहता है, तब उसका हैश कोड स्थिर रहना चाहिए। हैश को अपरिवर्तनीय फ़ील्ड पर आधारित करें; यदि प्रविष्टि के बाद कुंजी बदल जाए, तो संग्रह उसका पता खो सकता है।
using System;
public class Account
{
public readonly int Id; // immutable, safe to hash
public string Nickname; // mutable, do not hash
public Account(int id, string nick) { Id = id; Nickname = nick; }
public override bool Equals(object obj) => obj is Account a && a.Id == Id;
public override int GetHashCode() => Id.GetHashCode();
}
public class Program
{
public static void Main()
{
var acc = new Account(42, "old");
int h1 = acc.GetHashCode();
acc.Nickname = "new"; // does not change the hash
Console.WriteLine(h1 == acc.GetHashCode());
}
}शून्य फ़ील्ड संभालना
जब कोई फ़ील्ड शून्य हो सकता है, तो HashCode.Combine उसे सुरक्षित रूप से संभालता है। यदि आप स्वयं गणना करते हैं, तो NullReferenceException से बचने के लिए शून्य की जाँच करें।
using System;
public class Tag
{
public string Name;
public Tag(string name) { Name = name; }
public override bool Equals(object obj) => obj is Tag t && t.Name == Name;
public override int GetHashCode() => HashCode.Combine(Name); // null-safe
}
public class Program
{
public static void Main()
{
Console.WriteLine(new Tag(null).GetHashCode() == new Tag(null).GetHashCode());
}
}टक्कर सामान्य हैं
हैश कोड 32-बिट के होते हैं, इसलिए बड़े डेटा-समुच्चयों में टक्कर होना अपरिहार्य है। अच्छा हैश केवल मानों को इस तरह फैलाता है कि टक्करें कम हों; होने वाली टक्करों का समाधान Equals करता है।
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var set = new HashSet<int>();
for (int i = 0; i < 5; i++) set.Add(i);
// Equality still works perfectly even though hashing is imperfect in general
Console.WriteLine(set.Contains(3));
Console.WriteLine(set.Contains(99));
}
}रिकॉर्ड इसे आपके लिए उत्पन्न करते हैं
record अपने गुणों से सही GetHashCode स्वचालित रूप से उत्पन्न करता है और उसे अपने मान-आधारित Equals के अनुरूप रखता है। हैश निर्धारण सही ढंग से पाने का यह सबसे आसान तरीका है।
using System;
using System.Collections.Generic;
public record Coord(int X, int Y);
public class Program
{
public static void Main()
{
var set = new HashSet<Coord> { new Coord(1, 1) };
Console.WriteLine(set.Contains(new Coord(1, 1)));
}
}सही समानता-समर्थ प्रकार
सब कुछ एक साथ रखने पर: Equals और GetHashCode में समान फ़ील्ड, अपरिवर्तनीय कुंजियाँ और मानों को मिलाने के लिए HashCode.Combine। यह प्रकार शब्दकोश की कुंजी के रूप में बिना किसी समस्या के काम करता है।
using System;
using System.Collections.Generic;
public struct ProductKey
{
public string Sku;
public int Variant;
public ProductKey(string sku, int variant) { Sku = sku; Variant = variant; }
public override bool Equals(object obj)
=> obj is ProductKey k && k.Sku == Sku && k.Variant == Variant;
public override int GetHashCode() => HashCode.Combine(Sku, Variant);
}
public class Program
{
public static void Main()
{
var stock = new Dictionary<ProductKey, int>
{
[new ProductKey("ABC", 1)] = 10
};
Console.WriteLine(stock[new ProductKey("ABC", 1)]);
}
}स्वयं आज़माएँ
सुनिश्चित करें कि नियम कायम रहता है: दो समान कुंजियाँ बनाएँ और पुष्टि करें कि उनकी समानता तथा हैश कोड दोनों मेल खाते हैं, फिर उनका उपयोग एक set में करें।
using System;
using System.Collections.Generic;
public struct Name
{
public string First, Last;
public Name(string first, string last) { First = first; Last = last; }
public override bool Equals(object obj) => obj is Name n && n.First == First && n.Last == Last;
public override int GetHashCode() => HashCode.Combine(First, Last);
}
public class Program
{
public static void Main()
{
var a = new Name("Ada", "Lovelace");
var b = new Name("Ada", "Lovelace");
Console.WriteLine(a.Equals(b) + " " + (a.GetHashCode() == b.GetHashCode()));
var people = new HashSet<Name> { a };
Console.WriteLine(people.Contains(b));
}
}त्वरित जाँच
हैश निर्धारण के नियम को याद करें।
पुनरावलोकन
सही हैश निर्धारण हैश-आधारित संग्रहों को ठीक से काम करते रहने देता है।
- समान ऑब्जेक्ट को एक ही हैश कोड लौटाना चाहिए।
Equalsमें उपयोग किए गए उन्हीं फ़ील्ड परHashCode.Combineका उपयोग करें।- अपरिवर्तनीय फ़ील्ड का हैश बनाएँ, ताकि कुंजियाँ खोजने योग्य बनी रहें।
- टक्कर सामान्य हैं;
Equalsउनका समाधान करता है। - रिकॉर्ड सही कार्यान्वयन स्वचालित रूप से उत्पन्न करते हैं।
एआई शिक्षक के साथ C# सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 93
- पाठ
- 346
अक्सर पूछे जाने वाले प्रश्न
क्या “GetHashCode ओवरराइड करना” पाठ निःशुल्क है?
हाँ—“GetHashCode ओवरराइड करना” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और C# अकादमी पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। C# अकादमी पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“GetHashCode ओवरराइड करना” में मैं क्या सीखूँगा?
समानता और हैशिंग में संगति रखें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ C# अकादमी का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या C# अकादमी शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर C# अकादमी शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।
“GetHashCode ओवरराइड करना” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस C# अकादमी पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर C# अकादमी पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- IEquatable लागू करना
- GetHashCode ओवरराइड करना
- IComparable लागू करना
- कस्टम क्रम निर्धारण के लिए IComparer