2011-02-04 10 views
18

बीसीएल में कई जगहें हैं जहां कोई IEqualityComparer का उपयोग कर सकता है। Enumerable.Contains या Dictionary Constructor की तरह। अगर मैं default से खुश नहीं हूं तो मैं अपने तुलनात्मक प्रदान कर सकता हूं।क्या .NET में कोई भी "संदर्भकंपर" है?

कभी-कभी मैं जानना चाहता हूं कि संग्रह में है जो बहुत ही है जिसका संदर्भ है। किसी भी अन्य अर्थ में "बराबर" नहीं माना जाता है।
प्रश्न यह है: क्या बीसीएल में मानक समानता तुलनाकर्ता मौजूद है जो केवल विधि पर निर्भर करता है?

class ReferenceComparer<T> : IEqualityComparer<T> where T : class 
{ 
    private static ReferenceComparer<T> m_instance; 

    public static ReferenceComparer<T> Instance 
    { 
     get 
     { 
      return m_instance ?? (m_instance = new ReferenceComparer<T>()); 
     } 
    } 

    public bool Equals(T x, T y) 
    { 
     return ReferenceEquals(x, y); 
    } 

    public int GetHashCode(T obj) 
    { 
     return RuntimeHelpers.GetHashCode(obj); 
    } 
} 

मैं इसे अच्छी तरह से है और न ही परिदृश्यों के विचार बहुत सारे परीक्षण नहीं किया है, लेकिन यह Enumerable.Contains और Dictionary बहुत खुश करने के लिए लगता है:

एक है कि मैं अपने आप को लिखा था यह है।

+2

यह दुर्भाग्यपूर्ण है कि ये सभी संग्रह जावा-एस्क्यू तरीके से लिखे गए हैं, जिसके लिए आपको एक विशिष्ट इंटरफ़ेस लागू करने वाली कक्षा लिखने की आवश्यकता है। अगर वे आपको तुलना ऑपरेटर निर्दिष्ट करने के लिए एक प्रतिनिधि में पास करने की अनुमति देते हैं, तो आप सीधे 'object.ReferenceEquals' पास कर सकते हैं। मुझे लगता है कि ऐसा इसलिए है क्योंकि दो तरीकों की आवश्यकता है (तुलना और हैशकोड)। –

+0

जैसा कि मैं इसे समझता हूं, हालांकि, जावा समकक्ष को 'आईक्वालिटी कॉम्पैयर' में 'गेटहाशकोड' नहीं है, इसलिए जावा को प्रतिनिधि समर्थित होने पर इसे जावा में एक प्रतिनिधि के रूप में लागू किया जा सकता है। – Gabe

+1

@ बेन ऑरिप के उत्तर को देखें: http: // stackoverflow।कॉम/प्रश्न/98033/रैप-ए-प्रतिनिधि-इन-ए-इक्विलिटीकंपियर/1239337 # 1239337 –

उत्तर

17

जहां तक ​​मुझे पता है, बीसीएल किसी भी सार्वजनिक प्रकार का खुलासा नहीं करता है जो IEqualityComparer<T> को संदर्भ-समानता के साथ .NET 4.0 के रूप में लागू करता है।

  • System.Dynamic.Utils.ReferenceEqualityComparer<T> (System.Core में)
  • System.Xaml.Schema.ReferenceEqualityComparer<T> (System.Xaml में):

    हालांकि, वहाँ इस तरह के रूप कि ऐसा करने के आंतरिक प्रकार, का एक समूह होने के लिए दिखाई देते हैं।

मैं परावर्तक के साथ इन दो प्रकार के कार्यान्वयन पर एक नज़र ले लिया, और आप को पता है कि उन दोनों को एक तरह से लगभग तुम्हारा के समान है कि में लागू करने की, सिवाय इसके कि दिखाई खुशी होगी वे स्थैतिक उदाहरण के लिए आलसी-प्रारंभिकरण का उपयोग नहीं करते हैं (वे इसे प्रकार के लिए स्थिर निर्माता में बनाते हैं)।

एकमात्र संभव 'मुद्दा' मैं आपके कार्यान्वयन के बारे में सोच सकता हूं कि आलसी-प्रारंभिक धागा-सुरक्षित नहीं है, लेकिन चूंकि उदाहरण 'सस्ते' हैं और किसी भी राज्य पर नहीं हैं, जो नहीं बनाना चाहिए कोई भी बग या प्रमुख प्रदर्शन समस्याएं। यदि आप को सिंगलटन-पैटर्न को लागू करना चाहते हैं, तो आपको इसे ठीक से करना होगा।

+0

मेरी आलसी-प्रारंभिक विफलता का उल्लेख करने के लिए धन्यवाद। इस वर्ग के लिए स्थिर कन्स्ट्रक्टर में इंस्टेंस प्रारंभ करने के लिए सार्थक लग रहा है। हालांकि, धन्यवाद, मैं कहीं और भी गलती नहीं करूँगा। –

+0

@ अल्फा-माउस: चीयर्स। मैं कहूंगा कि मैं केवल इसके लिए कक्षा थ्रेड-सुरक्षित बनाने के लिए बाध्य नहीं महसूस करूंगा, जब तक कि मैं इसे * इस तरह * उपयोग करने का इरादा नहीं रखता। – Ani

+0

'System.Data.Entity.Infrastructure.ObjectReferenceEqualityComparer' भी है। –

2

मैं इस समाधान का उपयोग कर समाप्त करता हूं क्योंकि मुझे कोई कामकाज नहीं मिल सका।

गैर थ्रेड सुरक्षित कार्यान्वयन को ठीक करने के लिए, आप आसानी से एक स्थिर initiailizer का उपयोग कर सकते हैं।

public static ReferenceComparer<T> Instance => new ReferenceComparer<T>(); 

(अप-मतदान थ्रेड में कोई टिप्पणी करने के बजाय उत्तर के लिए खेद है, मैं कोई टिप्पणी अधिकारों के साथ एक नया खाता है, अभी तक)।

संबंधित मुद्दे