2008-12-03 13 views
8

संभव डुप्लिकेट:
Can’t operator == be applied to generic types in C#?समानता के लिए समान लेकिन अनियंत्रित जेनेरिक प्रकार के दो तत्वों की तुलना कैसे करें?

मैं निम्नलिखित सामान्य वर्ग और संकलक मिल गया है शिकायत है कि "Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'" (CS0019 देखें):

public class Example<TValue> 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 
      if (_value != value) // <<-- ERROR 
      { 
       _value= value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 

मैं तो TValue से class को बाधित करें, मैं Object.Equals() का उपयोग कर सकता हूं। चूंकि मुझे दोनों को structs और कक्षाओं के लिए इसकी आवश्यकता है, इसलिए अगर मैं इससे बच सकता हूं तो मैं बहुत खुश हूं।

तो सवाल यह है कि, मैं समानता के लिए समान लेकिन अनियंत्रित जेनेरिक प्रकार के दो तत्वों की तुलना कैसे कर सकता हूं?

+2

आप मूल्यों के लिए उपयोग क्यों नहीं कर सकते हैं? –

+0

डिफ़ॉल्ट रूप से, यदि आप संदर्भ वस्तुओं पर "object.Equals (a, b)" को कॉल करते हैं, तो "ऑब्जेक्ट। रेफरेंस एक्वाल्स (ए, बी)" कहा जाएगा। – TcKs

+0

@ टीसीके: डिफ़ॉल्ट रूप से, आप यह सुनिश्चित नहीं कर सकते कि व्युत्पन्न कक्षा में बराबर बराबर हो गया है या नहीं। – leppie

उत्तर

12

आप कुछ इस तरह की कोशिश की?

public class Example<TValue> 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 

      if (!object.Equals(_value, value)) 
      { 
       _value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 
+0

http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx का कहना है कि डिफ़ॉल्ट मान प्रकारों की तुलना बिटवाई की तुलना में की जाएगी, अन्यथा बराबर() विधि का उपयोग किया जाता है। यही वह है जिसे मैं ढूंढ रहा था। –

+4

ध्यान दें कि यह मूल्य प्रकारों के लिए मुक्केबाजी जुर्माना लगाएगा। –

2
  • बराबर() संदर्भ प्रकार के लिए मूल्य प्रकार
  • ReferenceEquals() के लिए
+1

मैं दो मामलों को प्रतिबिंबित करने या अन्यथा अंतर करने से बचाना चाहता हूं। वर्तमान में मैं एक सार आधार का उपयोग कर रहा हूं और इन बिट्स को दो बार कार्यान्वित कर रहा हूं: -/ –

+0

आप किस प्रतिबिंब का उपयोग कर रहे हैं? एक टाइपफॉफ़ करना (टीवीएयू) एक संकलन समय निरंतर है, और उस प्रकार की जांच करने के लिए वास्तव में कुछ भी लागत नहीं है। – leppie

0

मैं != ऑपरेटर यहां लागू नहीं किया जा सकता है क्योंकि ऐसे मामले, जहां उसका उपयोग नहीं किया जा सकता है। उदाहरण के लिए, != का उपयोग structs की तुलना करने के लिए नहीं किया जा सकता है, जब तक कि तुलना ऑपरेटर (==!=) ओवरलोड हो जाएं।

बेशक, आप int != int जैसे भाषा structs की तुलना कर सकते हैं, लेकिन मुझे यकीन नहीं है कि यह कैसे लागू किया गया है।

इसलिए, क्योंकि टीवीएयू कस्टम संरचना हो सकता है, यह != ऑपरेटर का उपयोग नहीं कर सकता है।

+0

हां, यह भी CS0019 की मेरी समझ थी। –

1

आईसीओम्पेर्बल एक विकल्प है?

public class Example<TValue> where TValue: IComparable 
{ 
    private TValue _value; 
    public TValue Value 
    { 
     get { return _value; } 
     set 
     { 

      if (_value.CompareTo(value) != 0) 
      { 
       _value = value; 
       OnPropertyChanged("Value"); 
      } 
     } 
    } 
} 
7

तीन विकल्प:

  • विवश TValue IEquatable<TValue> लागू करने के लिए और फिर फोन x.Equals(y)
  • प्रकार IEqualityComparer<TValue> का एक और पैरामीटर ले लो और का उपयोग करें कि
  • उपयोग EqualityComparer<TValue>.Default तुलना प्रदर्शन करने के लिए

आप हमेशा विकल्प 2 और 3 को मिश्रण और मिलान कर सकते हैं - डिफ़ॉल्ट रूप से डिफ़ॉल्ट तुलनाकर्ता के लिए डिफ़ॉल्ट, लेकिन एक विशिष्ट को प्रदान करने की अनुमति भी देता है।

0
public static bool operator ==(EntityBase<T> entity1, EntityBase<T> entity2) 
     { 
      if ((object)entity1 == null && (object)entity2 == null) 
      { 
       return true; 
      } 

      if ((object)entity1 == null || (object)entity2 == null) 
      { 
       return false; 
      } 

      if (Comparer<T>.Default.Compare(entity1.Id, entity2.Id) != 0) 
      { 
       return false; 
      } 

      return true; 
     } 
संबंधित मुद्दे