हमने पहले से ही .NET ढांचे के स्ट्रक्चर्स की ख़ासियत का विश्लेषण किया है जो कि वैल्यू टाइप्स का प्रतिनिधित्व करते हैं जब वैल्यू द्वारा ऑब्जेक्ट्स की तुलना करते हैं - स्ट्रक्चर्स का उदाहरण।
अब, मैं एक विशेष उदाहरण पर इस प्रक्रिया का वर्णन करने जा रहा हूं ताकि यह जांचा जा सके कि क्या यह हमें सामान्य रूप से मूल्य के आधार पर वस्तु तुलना के उपयोग को निर्धारित करने की अनुमति देगा और इस प्रकार, वस्तुओं की तुलना के एक नमूने को मूल्य-वर्ग उदाहरणों से सरल बनाने के लिए जो संदर्भ का प्रतिनिधित्व करते हैं प्रकार।
व्यक्ति संरचना संरचना:
using System; namespace HelloEquatable { public struct PersonStruct : IEquatable<PersonStruct>, IEquatable<PersonStruct?> { private static int GetHashCodeHelper(int[] subCodes) { int result = subCodes[0]; for (int i = 1; i < subCodes.Length; i++) result = unchecked(result * 397) ^ subCodes[i]; return result; } private static string NormalizeName(string name) => name?.Trim() ?? string.Empty; private static DateTime? NormalizeDate(DateTime? date) => date?.Date; public string FirstName { get; } public string LastName { get; } public DateTime? BirthDate { get; } public PersonStruct(string firstName, string lastName, DateTime? birthDate) { this.FirstName = NormalizeName(firstName); this.LastName = NormalizeName(lastName); this.BirthDate = NormalizeDate(birthDate); } public override int GetHashCode() => GetHashCodeHelper( new int[] { this.FirstName.GetHashCode(), this.LastName.GetHashCode(), this.BirthDate.GetHashCode() } ); public static bool Equals(PersonStruct first, PersonStruct second) => first.BirthDate == second.BirthDate && first.FirstName == second.FirstName && first.LastName == second.LastName; public static bool operator ==(PersonStruct first, PersonStruct second) => Equals(first, second); public static bool operator !=(PersonStruct first, PersonStruct second) => !Equals(first, second); public bool Equals(PersonStruct other) => Equals(this, other); public static bool Equals(PersonStruct? first, PersonStruct? second) => first == second; // Alternate version: //public static bool Equals(PersonStruct? first, PersonStruct? second) => // first.HasValue == second.HasValue && // ( // !first.HasValue || Equals(first.Value, second.Value) // ); public bool Equals(PersonStruct? other) => this == other; // Alternate version: //public bool Equals(PersonStruct? other) => // other.HasValue && Equals(this, other.Value); public override bool Equals(object obj) => (obj is PersonStruct) && Equals(this, (PersonStruct)obj); // Alternate version: //public override bool Equals(object obj) => // obj != null && // this.GetType() == obj.GetType() && // Equals(this, (PersonStruct)obj); } }
जैसा कि आप देख सकते हैं, यह उदाहरण संरचना द्वारा छोटा और आसान है, क्योंकि structs के उदाहरण शून्य नहीं हैं और उपयोगकर्ता द्वारा परिभाषित structs से प्राप्त करना संभव नहीं है। हमने अपने पिछले लेख में वर्ग उदाहरणों के लिए मूल्य द्वारा तुलना को लागू करने के लिए पहले ही विशिष्टताओं पर चर्चा की है।
इसके अलावा, हमने ऑब्जेक्ट तुलना के लिए फ़ील्ड निर्धारित किए हैं और साथ ही GetHashCode () पद्धति को लागू किया है।
तुलना के तरीके और ऑपरेटरों को निम्नलिखित क्रम में लागू किया गया है:
- संरचनाओं के दो उदाहरणों की तुलना करने के लिए, हमने PersonStruct.Equals(PersonStruct, PersonStruct) स्थिर विधि लागू की है। अन्य विधियों और ऑपरेटरों को लागू करते समय हम इस पद्धति का उपयोग संदर्भ तुलना पद्धति के रूप में करेंगे। इसके अतिरिक्त, यह उन भाषाओं में संरचनाओं के उदाहरणों की तुलना करने के लिए लागू किया जा सकता है जो ऑपरेटरों का समर्थन नहीं करते हैं।
- द पर्सनस्ट्रक्चर.==(पर्सनस्ट्रक्चर, पर्सनस्ट्रक्चर) और पर्सनस्ट्रक्चर।!=(पर्सनस्ट्रक्चर, पर्सनस्ट्रक्चर) ऑपरेटरों को भी लागू किया गया है। यह ध्यान दिया जाना चाहिए कि C# कंपाइलर में निम्नलिखित विशेषताएं हैं:
- आप अतिभारित ऑपरेटरों के साथ तुलना कर सकते हैं T.==(T, T) और T.!=(T, T) Nullable(Of T) में
- मूल्य समानता की जांच करने से पहले, एक कंपाइलर यह सत्यापित कर सकता है कि क्या स्ट्रक्चर्स के उदाहरणों का एक वैध मूल्य है। इसके अलावा, कंपाइलर स्ट्रक्चर्स के इंस्टेंस को ऑब्जेक्ट्स में रैप नहीं करता है।
- इस प्रकार, Nullable(Of T) संरचना के उदाहरणों की तुलना बिना टाइप किए गए शून्य मान के साथ करने से ==(T, T) या T.!=(T, T) ऑपरेटरों को कॉल किया जाता है, जबकि Nullable के उदाहरणों की तुलना की जाती है। टी) ओवरलोड ऑपरेटरों के बिना संरचना और, परिणामस्वरूप, किसी उदाहरण को ऑब्जेक्ट में लपेटने में।
- PersonStruct.Equals(PersonStruct) विधि (IEquatable(PersonStruct का कार्यान्वयन)) को PersonStruct.Equals(PersonStruct, PersonStruct) पद्धति को कॉल करके लागू किया गया है।
- ऑब्जेक्ट्स में स्ट्रक्चर्स के इंस्टेंस को लपेटने से बचने के लिए, जब हमारे पास एक या दो Nullable(Of PersonStruct) इंस्टेंस होते हैं, तो निम्न विधियों को लागू करना संभव है:
- PersonStruct.Equals(PersonStruct?, PersonStruct?), PersonStruct.==(PersonStruct, PersonStruct) ऑपरेटर की कॉल के रूप में, ऑब्जेक्ट में दोनों तर्कों के स्ट्रक्चर के उदाहरणों को लपेटने और ऑब्जेक्ट को कॉल करने से बचने के लिए उपयोग किया जाता है। ऑब्जेक्ट, ऑब्जेक्ट) विधि यदि तर्कों में से कम से कम एक अशक्त (व्यक्ति संरचना का) उदाहरण है। इसके अतिरिक्त, आप इस पद्धति का उपयोग उन भाषाओं में Nullable(Of PersonStruct) उदाहरणों की तुलना करने के लिए कर सकते हैं जो ऑपरेटरों का समर्थन नहीं करती हैं। कोड में, आपको यह समझाते हुए टिप्पणियां मिल सकती हैं कि यदि सी # कंपाइलर टी ==(टी, टी) और टी। =(टी, टी) ऑपरेटरों का उपयोग करने में सक्षम नहीं था, तो यह विधि कैसे कार्यान्वित की जा सकती है। टी) तर्क।
- PersonStruct.Equals(PersonStruct?) - IEquatable(Of PersonStruct?) इंटरफ़ेस का कार्यान्वयन जिसका उपयोग Nullable(Of PersonStruct) तर्कों को वस्तुओं में लपेटने और PersonStruct.Equals(Object) विधि को कॉल करने से बचने के लिए किया जाता है। इसे पर्सनस्ट्रक्चर की कॉल के रूप में कार्यान्वित किया जाता है। ==(पर्सनस्ट्रक्चर, पर्सनस्ट्रक्चर) ऑपरेटर टी। ==(टी, टी) और टी का उपयोग करने के लिए टिप्पणी कोड के साथ! =(टी, टी) ऑपरेटरों के लिए नलबल (टी का) ) तर्क।
- PersonStruct.Equals(Object) - जो Object.Equals(Object) मेथड को ओवरराइड करता है। यह is ऑपरेटर का उपयोग करके पर्सनस्ट्रक्चर को तर्क देकर और PersonStruct.Equals(PersonStruct, PersonStruct) को कॉल करके मौजूदा ऑब्जेक्ट के प्रकार के साथ एक तर्क प्रकार की संगतता की जांच करके कार्यान्वित किया जाता है।
नोट:
- IEquatable(Of PersonStruct?) का कार्यान्वयन - IEquatable(Of Nullable(Of PersonStruct))इंटरफ़ेस प्लेटफ़ॉर्म में विशेष मुद्दों को दिखाने के लिए कार्य करता है जब स्ट्रक्चर्स के साथ काम करते हैं जहां वस्तुओं में इंस्टेंस को लपेटना हमारी अपेक्षा से तेज़ी से होता है।
- वास्तविक परियोजनाओं में, बशर्ते कि प्रदर्शन में सुधार करना आवश्यक न हो, IEquatable(Of Nullable(Of T)) का कार्यान्वयन आर्किटेक्चर कारणों से लागू नहीं होता है - हमें किसी भी प्रकार के लिए टाइप किए गए IEquatable को T प्रकार में लागू नहीं करना चाहिए।
- सामान्य तौर पर, अलग-अलग अनुकूलन के साथ कोड को अभिभूत करना आवश्यक नहीं है।
संरचनाओं के लिए, हम उपयोगकर्ता परिभाषित संरचनाओं की विरासत से बचकर मूल्य की तुलना को अधिक सरल और अधिक उत्पादक बनाने के लिए प्राप्त कर सकते हैं और वस्तुओं को शून्य पर जांचने की आवश्यकता है। इसके अलावा, हम एक नए तर्क की निगरानी कर सकते हैं जो Nullable(Of T) तर्कों का समर्थन करता है।
अपने भविष्य के प्रकाशन में, मैं निम्नलिखित बिंदुओं को संक्षेप में बताऊंगा:
- जब मूल्य के आधार पर वस्तुओं की तुलना करना एक अच्छा विचार है;
- हम वस्तुओं के लिए मूल्य द्वारा तुलना के कार्यान्वयन को कैसे सरल बना सकते हैं - संदर्भ प्रकारों का प्रतिनिधित्व करने वाले वर्ग उदाहरण।
यह भी पढ़ें:
मूल्य द्वारा वस्तुओं की तुलना करना। भाग 1:शुरुआत
मूल्य द्वारा वस्तुओं की तुलना करना। भाग 2:समान पद्धति के कार्यान्वयन नोट्स
मूल्य द्वारा वस्तुओं की तुलना करना। भाग 3:टाइप-विशिष्ट समान और समानता ऑपरेटर्स
मूल्य द्वारा वस्तुओं की तुलना करना। भाग 4:वंशानुक्रम और तुलना ऑपरेटर्स
मूल्य द्वारा वस्तुओं की तुलना करना। भाग 5:संरचना समानता का मुद्दा