ऑपरेटर == को C # में सामान्य प्रकारों पर लागू नहीं किया जा सकता है?


326

MSDN== में ऑपरेटर के प्रलेखन के अनुसार ,

पूर्वनिर्धारित मूल्य प्रकारों के लिए, समानता ऑपरेटर (==) सही साबित होता है यदि उसके ऑपरेंड के मूल्य समान हैं, अन्यथा झूठे हैं। स्ट्रिंग के अलावा अन्य संदर्भ प्रकारों के लिए, == सही है यदि इसके दो ऑपरेंड एक ही ऑब्जेक्ट को संदर्भित करते हैं। स्ट्रिंग प्रकार के लिए, == स्ट्रिंग्स के मूल्यों की तुलना करता है। उपयोगकर्ता-परिभाषित मूल्य प्रकार == ऑपरेटर (ऑपरेटर देखें) को अधिभारित कर सकते हैं। तो उपयोगकर्ता-परिभाषित संदर्भ प्रकार, हालांकि डिफ़ॉल्ट रूप से == पूर्वनिर्धारित और उपयोगकर्ता-परिभाषित संदर्भ प्रकार दोनों के लिए ऊपर वर्णित अनुसार व्यवहार करते हैं।

तो यह कोड स्निपेट संकलन में विफल क्यों है?

bool Compare<T>(T x, T y) { return x == y; }

मुझे त्रुटि ऑपरेटर '==' टाइप 'T' और 'T' के ऑपरेंड पर लागू नहीं किया जा सकता है । मुझे आश्चर्य है कि क्यों, जहां तक ​​मैं समझता हूं कि ==ऑपरेटर सभी प्रकार के लिए पूर्वनिर्धारित है?

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

लेकिन, यदि मैं एक संदर्भ प्रकार का उपयोग कर रहा हूं, तो क्या ==ऑपरेटर पूर्वनिर्धारित संदर्भ तुलना का उपयोग करेगा, या क्या यह ऑपरेटर के अतिभारित संस्करण का उपयोग करेगा यदि कोई प्रकार परिभाषित किया गया है?

संपादन 2: परीक्षण और त्रुटि के माध्यम से, हमने पाया कि ==ऑपरेटर अप्रतिबंधित जेनेरिक प्रकार का उपयोग करते समय पूर्वनिर्धारित संदर्भ तुलना का उपयोग करेगा। वास्तव में, कंपाइलर सबसे अच्छे तरीके का उपयोग करेगा जो इसे प्रतिबंधित प्रकार के तर्क के लिए मिल सकता है, लेकिन आगे नहीं दिखेगा। उदाहरण के लिए, नीचे दिया गया कोड हमेशा प्रिंट होगा true, यहां तक ​​कि जब Test.test<B>(new B(), new B())कहा जाता है:

class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }

अपने अनुवर्ती प्रश्न के उत्तर के लिए मेरा उत्तर फिर से देखें।
जियोवानी गैल्बो

यह समझना उपयोगी हो सकता है कि जेनरिक के बिना भी, कुछ ऐसे प्रकार हैं जिनके लिए ==एक ही प्रकार के दो ऑपरेंड के बीच अनुमति नहीं है। यह structप्रकारों के लिए सच है ("पूर्व-परिभाषित" प्रकारों को छोड़कर) जो ओवरलोड नहीं करते हैं operator ==। एक सरल उदाहरण के रूप में, यह कोशिश करें:var map = typeof(string).GetInterfaceMap(typeof(ICloneable)); Console.WriteLine(map == map); /* compile-time error */
जेपी स्टिग नीलसन

मेरी अपनी पुरानी टिप्पणी जारी है। उदाहरण के लिए ( अन्य थ्रेड देखें ), var kvp1 = new KeyValuePair<int, int>(); var kvp2 = kvp1;तब, आप जाँच नहीं कर सकते kvp1 == kvp2क्योंकि KeyValuePair<,>एक संरचना है, यह C # पूर्व-निर्धारित प्रकार नहीं है, और यह ओवरलोड नहीं करता है operator ==। फिर भी एक उदाहरण दिया गया var li = new List<int>(); var e1 = li.GetEnumerator(); var e2 = e1;है जिसके साथ आप ऐसा नहीं कर सकते हैं e1 == e2(यहां हमारे पास नेस्टेड स्ट्रक्चर List<>.Enumerator( "List`1+Enumerator[T]"रनटाइम द्वारा कॉल किया गया है) जो ओवरलोड नहीं करता है ==)।
जेपी स्टिग नीलसन

RE: "तो यह कोड स्निपेट संकलन में विफल क्यों है?" - एर ... क्योंकि तुम एक boolसे नहीं लौट सकते void...
BrainSlugs83

1
@ BrainSlugs83 10 साल पुराने बग को पकड़ने के लिए धन्यवाद!
होसम ऐली

जवाबों:


143

"... डिफ़ॉल्ट रूप से == पूर्वनिर्धारित और उपयोगकर्ता-परिभाषित संदर्भ प्रकार दोनों के लिए ऊपर वर्णित व्यवहार करता है।"

टाइप टी आवश्यक रूप से एक संदर्भ प्रकार नहीं है, इसलिए संकलक उस धारणा को नहीं बना सकता है।

हालाँकि, यह संकलित होगा क्योंकि यह अधिक स्पष्ट है:

    bool Compare<T>(T x, T y) where T : class
    {
        return x == y;
    }

अतिरिक्त प्रश्न का अनुसरण करें, "लेकिन, यदि मैं एक संदर्भ प्रकार का उपयोग कर रहा हूं, तो क्या == ऑपरेटर पूर्वनिर्धारित संदर्भ तुलना का उपयोग करेगा, या क्या यह ऑपरेटर के अतिभारित संस्करण का उपयोग करेगा यदि कोई प्रकार परिभाषित किया गया है?"

मुझे लगता है कि == पीढ़ी पर अधिभार संस्करण का उपयोग करेगा, लेकिन निम्नलिखित परीक्षण अन्यथा प्रदर्शित करता है। दिलचस्प ... मुझे यह जानकर अच्छा लगेगा! अगर किसी को पता है तो कृपया शेयर करें

namespace TestProject
{
 class Program
 {
    static void Main(string[] args)
    {
        Test a = new Test();
        Test b = new Test();

        Console.WriteLine("Inline:");
        bool x = a == b;
        Console.WriteLine("Generic:");
        Compare<Test>(a, b);

    }


    static bool Compare<T>(T x, T y) where T : class
    {
        return x == y;
    }
 }

 class Test
 {
    public static bool operator ==(Test a, Test b)
    {
        Console.WriteLine("Overloaded == called");
        return a.Equals(b);
    }

    public static bool operator !=(Test a, Test b)
    {
        Console.WriteLine("Overloaded != called");
        return a.Equals(b);
    }
  }
}

उत्पादन

इनलाइन: अतिभारित == कहा जाता है

सामान्य:

जारी रखने के लिए किसी भी कुंजी को दबाएं । । ।

2 का पालन करें

मैं यह बताना चाहता हूं कि अपनी तुलना पद्धति को बदलना

    static bool Compare<T>(T x, T y) where T : Test
    {
        return x == y;
    }

अतिभारित होने के कारण == ऑपरेटर को बुलाया जाएगा। मुझे लगता है कि टाइप को निर्दिष्ट किए बिना ( जहां पर ), कंपाइलर यह अनुमान नहीं लगा सकता है कि उसे ओवरलोड ऑपरेटर का उपयोग करना चाहिए ... हालांकि मुझे लगता है कि उस प्रकार को निर्दिष्ट किए बिना भी उस निर्णय को करने के लिए पर्याप्त जानकारी होगी।


धन्यवाद। मैंने देखा कि बयान केवल संदर्भ प्रकारों के बारे में था।
होसम ऐली

4
पुन :: 2 का पालन करें: वास्तव में संकलक इसे सबसे अच्छी विधि का पता लगाएगा, जो इस मामले में है। Test.op_Equal। लेकिन अगर आपके पास एक वर्ग था जो टेस्ट से निकलता है और ऑपरेटर को ओवरराइड करता है, तो टेस्ट के ऑपरेटर को अभी भी बुलाया जाएगा।
होसम ऐली

4
मैं अच्छा अभ्यास करता हूं कि मैं यह बताना चाहूंगा कि आपको हमेशा वास्तविक तुलना ओवरराइड Equalsविधि ( ==ऑपरेटर में नहीं ) के अंदर करनी चाहिए ।
jpbochi

11
अधिभार संकल्प संकलन-समय होता है। इसलिए जब हमारे पास ==सामान्य प्रकार Tऔर T, सबसे अच्छा अधिभार होता है, तो यह देखते हुए कि क्या अड़चनें होती हैं T(एक विशेष नियम है कि यह कभी भी इसके लिए एक मूल्य-प्रकार बॉक्स नहीं करेगा (जो एक व्यर्थ परिणाम देगा), इसलिए वहाँ होना चाहिए कुछ बाधा यह एक संदर्भ प्रकार की गारंटी है)। अपने अनुवर्ती 2 में , यदि आप DerivedTestवस्तुओं के साथ आते हैं, और DerivedTestप्राप्त करते हैं, Testलेकिन एक नया अधिभार पेश करता है ==, तो आपको फिर से "समस्या" होगी। जिसे अधिभार कहा जाता है, संकलन-समय पर IL में "बर्न" किया जाता है।
जेपी स्टिग नीलसन 18

1
सामान्य तौर पर यह सामान्य संदर्भ प्रकारों के लिए काम करने लगता है (जहाँ आप इस समानता के संदर्भ समानता पर होने की उम्मीद करेंगे), लेकिन तार के लिए यह संदर्भ समानता का उपयोग करने के लिए भी लगता है - इसलिए आप 2 समान तारों की तुलना कर सकते हैं और == (जब में वर्ग बाधा के साथ सामान्य विधि) कहते हैं कि वे अलग हैं।
जोनिरा

291

जैसा कि दूसरों ने कहा है, यह केवल तभी काम करेगा जब टी एक संदर्भ प्रकार होने के लिए विवश हो। किसी भी बाधा के बिना, आप अशक्त के साथ तुलना कर सकते हैं, लेकिन केवल अशक्त - और यह तुलना हमेशा गैर-शून्य मान प्रकार के लिए झूठी होगी।

बराबरी को कॉल करने के बजाय, इसका उपयोग करना बेहतर है IComparer<T>- और यदि आपके पास अधिक जानकारी नहीं है, EqualityComparer<T>.Defaultतो एक अच्छा विकल्प है:

public bool Compare<T>(T x, T y)
{
    return EqualityComparer<T>.Default.Equals(x, y);
}

इसके अलावा, यह बॉक्सिंग / कास्टिंग से बचा जाता है।


धन्यवाद। मैं एक साधारण रैपर क्लास लिखने की कोशिश कर रहा था, इसलिए मैं बस ऑपरेशन को वास्तविक लिपटे सदस्य को सौंपना चाहता था। लेकिन EqualityComparer <T> .Default के बारे में जानना निश्चित रूप से मेरे लिए महत्वपूर्ण है। :)
होसम एली

एक तरफ माइनर, जॉन; आप मेरी पोस्ट पर टिप्पणी re pobox vs yoda नोट करना चाह सकते हैं।
मार्क Gravell

4
EqualityComparer <T>
chakrit

1
+1 यह इंगित करने के लिए कि यह शून्य की तुलना कर सकता है और गैर अशक्त मूल्य प्रकार के लिए यह हमेशा गलत होगा
जलाल ने कहा कि

@ ब्ल्यूराज: हां, क्योंकि अशक्त शाब्दिक की तुलना के लिए विशेष नियम हैं। 4. "बिना किसी बाधा के, आप अशक्त के साथ तुलना कर सकते हैं, लेकिन केवल अशक्त"। यह पहले से ही जवाब में है। तो, वास्तव में यह सही क्यों नहीं हो सकता है?
जॉन स्कीट

41

सामान्य तौर पर, ऐसी EqualityComparer<T>.Default.Equalsकिसी भी चीज के साथ काम करना चाहिए जो लागू होती है IEquatable<T>, या जिसे एक समझदार Equalsकार्यान्वयन है।

यदि, हालांकि, ==और Equalsकिसी कारण से अलग तरीके से लागू किया जाता है, तो जेनेरिक ऑपरेटरों पर मेरा काम उपयोगी होना चाहिए; यह (दूसरों के बीच) के ऑपरेटर संस्करणों का समर्थन करता है :

  • समान (T मान 1, T मान 2)
  • NotEqual (टी मान 1, टी मान 2)
  • ग्रेटरथन (टी मान 1, टी मान 2)
  • लेथन (टी मान १, टी मान २)
  • ग्रेटरथॉर्नक्वल (टी मान 1, टी मान 2)
  • लेसनथ्रॉक्वेल (टी मान 1, टी मान 2)

बहुत दिलचस्प पुस्तकालय! :) (साइड नोट: क्या मैं www.yoda.arachsys.com के लिंक का उपयोग करने का सुझाव दे सकता हूं, क्योंकि मेरे कार्यस्थल में पॉबॉक्स एक को फ़ायरवॉल द्वारा अवरुद्ध किया गया था? यह संभव है कि दूसरों को एक ही मुद्दे का सामना करना पड़े।)
होसम एली

विचार यह है कि pobox.com/~skeet हमेशा मेरी वेबसाइट को इंगित करेगा - भले ही वह कहीं और चले। मैं पोस्टपैरिटी के लिए pobox.com के माध्यम से लिंक पोस्ट करता हूं - लेकिन आप वर्तमान में इसके बजाय yoda.arachsys.com को स्थानापन्न कर सकते हैं ।
जॉन स्कीट

Pobox.com के साथ समस्या यह है कि यह एक वेब-आधारित ई-मेल सेवा है (या इसलिए कंपनी का फ़ायरवॉल कहता है), इसलिए यह अवरुद्ध है। इसलिए मैं इसके लिंक का अनुसरण नहीं कर सका।
होसम ऐली

"यदि, हालांकि, == और बराबरी किसी कारण से अलग तरीके से लागू की जाती है" - पवित्र धूम्रपान! फिर भी क्या! हो सकता है कि मुझे इसके विपरीत एक उपयोग के मामले को देखने की आवश्यकता है, लेकिन डायवर्जेंट बराबर शब्दार्थ के साथ एक पुस्तकालय संभवतः जेनेरिक के साथ परेशानी की तुलना में बड़ी समस्याओं में चलेगा।
एडवर्ड ब्रे जूल

@EdwardBrey तुम गलत नहीं हो; यह अच्छा होगा अगर संकलक कि लागू कर सकता है, लेकिन ...
मार्क Gravell

31

इतने सारे उत्तर, और एक भी व्यक्ति WHY की व्याख्या क्यों नहीं करता? (जो जियोवन्नी ने स्पष्ट रूप से पूछा) ...

.NET जेनरिक C ++ टेम्प्लेट की तरह कार्य नहीं करता है। C ++ टेम्प्लेट में, वास्तविक टेम्प्लेट पैरामीटर ज्ञात होने के बाद अधिभार संकल्प होता है।

.NET जेनरिक में (C # सहित), वास्तविक सामान्य पैरामीटर को जाने बिना अधिभार संकल्प होता है। केवल सूचना संकलक का उपयोग करने के लिए फ़ंक्शन का चयन करने के लिए उपयोग कर सकते हैं सामान्य मापदंडों पर प्रकार की बाधाओं से आता है।


2
लेकिन संकलक उन्हें एक सामान्य वस्तु के रूप में क्यों नहीं मान सकते हैं? ==सभी प्रकार के लिए सभी कार्यों के बाद यह संदर्भ प्रकार या मूल्य प्रकार होना चाहिए। यह वह प्रश्न होना चाहिए जिसके बारे में मुझे नहीं लगता कि आपने उत्तर दिया है।
नवफाल

4
@nawfal: वास्तव में नहीं, ==सभी मूल्य प्रकारों के लिए काम नहीं करता है। इससे भी महत्वपूर्ण बात, यह सभी प्रकारों के लिए समान अर्थ नहीं रखता है, इसलिए संकलक को यह नहीं पता है कि इसके साथ क्या करना है।
बेन वोइगट

1
बेन, ओह हाँ मैंने कस्टम संरचना को याद किया हम बिना किसी के बना सकते हैं ==। क्या आप उस भाग को भी अपने उत्तर में शामिल कर सकते हैं जैसा कि मुझे लगता है कि यहाँ मुख्य बिंदु है
nawfal

12

संकलन नहीं जान सकता है कि T एक संरचना (मूल्य प्रकार) नहीं हो सकता है। तो आपको यह बताना होगा कि यह केवल संदर्भ प्रकार का हो सकता है जो मुझे लगता है:

bool Compare<T>(T x, T y) where T : class { return x == y; }

ऐसा इसलिए है क्योंकि यदि T एक मान प्रकार हो सकता है, तो ऐसे मामले हो सकते हैं जहां x == yबीमार हो जाएंगे - ऐसे मामलों में जब किसी प्रकार का ऑपरेटर == परिभाषित नहीं होता है। इसके लिए वही होगा जो अधिक स्पष्ट है:

void CallFoo<T>(T x) { x.foo(); }

यह भी विफल रहता है, क्योंकि आप एक प्रकार का टी पास कर सकते हैं जिसमें एक फ़ंक्शन फू नहीं होगा। C # आपको यह सुनिश्चित करने के लिए मजबूर करता है कि सभी संभावित प्रकारों में हमेशा एक फ़ंक्शन फू है। वह जहां क्लॉज द्वारा किया जाता है।


1
स्पष्टीकरण के लिए धन्यवाद। मुझे नहीं पता था कि मूल्य प्रकार बॉक्स से बाहर == ऑपरेटर का समर्थन नहीं करते थे।
होसम ऐली

1
होसम, मैंने gmcs (मोनो) के साथ परीक्षण किया, और यह हमेशा संदर्भों की तुलना करता है। (यानी यह वैकल्पिक रूप से परिभाषित ऑपरेटर == टी के लिए उपयोग नहीं करता है)
जोहान्स स्काउब -

इस समाधान के साथ एक चेतावनी है: ऑपरेटर == अतिभारित नहीं किया जा सकता है; इस StackOverflow प्रश्न को देखें
दिमित्री सी।

8

ऐसा प्रतीत होता है कि वर्ग की कमी के बिना:

bool Compare<T> (T x, T y) where T: class
{
    return x == y;
}

एक को एहसास होना चाहिए कि ऑपरेटर में classकमी के दौरान विरासत में मिला है , जबकि एक संरचना ओवरराइड करती है ।Equals==Object.EqualsValueType.Equals

ध्यान दें कि:

bool Compare<T> (T x, T y) where T: struct
{
    return x == y;
}

भी एक ही संकलक त्रुटि देता है।

अभी तक मुझे समझ में नहीं आया है कि मूल्य प्रकार की समानता ऑपरेटर की तुलना संकलक द्वारा अस्वीकार क्यों की जाती है। मैं एक तथ्य के लिए जानता हूं, हालांकि यह काम करता है:

bool Compare<T> (T x, T y)
{
    return x.Equals(y);
}

यू पता im कुल सी # नोब। लेकिन मुझे लगता है कि यह विफल हो जाता है क्योंकि संकलक को पता नहीं है कि क्या करना है। चूंकि T अभी तक ज्ञात नहीं है, इसलिए जो किया जाता है वह उस प्रकार T पर निर्भर करता है यदि मान प्रकार की अनुमति होगी। संदर्भों के लिए, संदर्भों की तुलना टी के बिना की जाती है। यदि आप करते हैं।
जोहान्स स्काउब - 7

लेकिन यदि आप एक मूल्य प्रकार पर == करते हैं, तो मूल्य प्रकार को उस ऑपरेटर को लागू करने के लिए आवश्यक नहीं है।
जोहान्स शाउब - 7

यह समझ में आता है, litb :) यह संभव है कि उपयोगकर्ता-परिभाषित संरचनाएं अधिभार == नहीं हैं, इसलिए कंपाइलर विफल हो जाता है।
जॉन लीमजाप

2
पहली तुलना विधि का उपयोग नहीं करता है Object.Equalsलेकिन इसके बजाय संदर्भ समानता का परीक्षण करता है । उदाहरण के लिए, Compare("0", 0.ToString())असत्य वापस आ जाएगा, क्योंकि तर्क अलग-अलग तार के संदर्भ होंगे, दोनों में एक शून्य केवल उनके चरित्र के रूप में है।
सुपरकैट

1
उस पिछले एक पर माइनर गोचरा- आपने इसे स्ट्रक्चर्स तक सीमित नहीं रखा है, इसलिए ऐसा NullReferenceExceptionहो सकता है।
फ्लाईन 1179

6

खैर मेरे मामले में मैं समानता ऑपरेटर को इकाई-परीक्षण करना चाहता था। मुझे स्पष्ट रूप से सामान्य प्रकार की स्थापना के बिना समानता ऑपरेटरों के तहत कोड को कॉल करने की आवश्यकता थी। सलाह देता है के लिए EqualityComparerके रूप में सहायक नहीं थे EqualityComparerबुलाया Equalsविधि नहीं बल्कि समानता ऑपरेटर।

यहाँ बताया गया है कि इस प्रकार से मैंने जेनेरिक प्रकारों के साथ काम कर लिया है LINQ। यह के लिए सही कोड कहता है ==और !=ऑपरेटरों:

/// <summary>
/// Gets the result of "a == b"
/// </summary>
public bool GetEqualityOperatorResult<T>(T a, T b)
{
    // declare the parameters
    var paramA = Expression.Parameter(typeof(T), nameof(a));
    var paramB = Expression.Parameter(typeof(T), nameof(b));
    // get equality expression for the parameters
    var body = Expression.Equal(paramA, paramB);
    // compile it
    var invokeEqualityOperator = Expression.Lambda<Func<T, T, bool>>(body, paramA, paramB).Compile();
    // call it
    return invokeEqualityOperator(a, b);
}

/// <summary>
/// Gets the result of "a =! b"
/// </summary>
public bool GetInequalityOperatorResult<T>(T a, T b)
{
    // declare the parameters
    var paramA = Expression.Parameter(typeof(T), nameof(a));
    var paramB = Expression.Parameter(typeof(T), nameof(b));
    // get equality expression for the parameters
    var body = Expression.NotEqual(paramA, paramB);
    // compile it
    var invokeInequalityOperator = Expression.Lambda<Func<T, T, bool>>(body, paramA, paramB).Compile();
    // call it
    return invokeInequalityOperator(a, b);
}

4

यहां इसके लिए MSDN कनेक्ट प्रविष्टि है

एलेक्स टर्नर के जवाब के साथ शुरू होता है:

दुर्भाग्य से, यह व्यवहार डिजाइन द्वारा है और प्रकार के मापदंडों के साथ == के उपयोग को सक्षम करने के लिए एक आसान समाधान नहीं है जिसमें मूल्य प्रकार शामिल हो सकते हैं।


4

यदि आप यह सुनिश्चित करना चाहते हैं कि आपके कस्टम प्रकार के ऑपरेटरों को बुलाया जाए तो आप प्रतिबिंब के माध्यम से ऐसा कर सकते हैं। बस अपने सामान्य पैरामीटर का उपयोग करके टाइप करें और इच्छित ऑपरेटर के लिए MethodInfo को पुनः प्राप्त करें (जैसे op_Equality, op_Inequality, op_LessThan ...)।

var methodInfo = typeof (T).GetMethod("op_Equality", 
                             BindingFlags.Static | BindingFlags.Public);    

फिर MethodInfo के इनवोक विधि का उपयोग करके ऑपरेटर को निष्पादित करें और पैरामीटर के रूप में ऑब्जेक्ट में पास करें।

var result = (bool) methodInfo.Invoke(null, new object[] { object1, object2});

यह आपके अतिभारित ऑपरेटर का आह्वान करेगा, न कि जेनेरिक पैरामीटर पर लागू बाधाओं से परिभाषित। व्यावहारिक नहीं हो सकता है, लेकिन एक सामान्य आधार वर्ग का उपयोग करते समय अपने ऑपरेटरों के परीक्षण के लिए यूनिट में काम आ सकता है जिसमें कुछ परीक्षण शामिल हैं।


3

मैंने निम्नलिखित फ़ंक्शन को नवीनतम msdn को देखते हुए लिखा। यह आसानी से दो वस्तुओं की तुलना कर सकता है xऔर y:

static bool IsLessThan(T x, T y) 
{
    return ((IComparable)(x)).CompareTo(y) <= 0;
}

4
आप अपने बूलियन्स से छुटकारा पा सकते हैं और लिख सकते हैंreturn ((IComparable)(x)).CompareTo(y) <= 0;
aloisdg

1

bool Compare(T x, T y) where T : class { return x == y; }

उपर्युक्त कार्य करेगा क्योंकि == को उपयोगकर्ता-परिभाषित संदर्भ प्रकारों के मामले में ध्यान रखा जाता है।
मूल्य प्रकारों के मामले में, == को ओवरराइड किया जा सकता है। किस मामले में, "=!" को भी परिभाषित किया जाना चाहिए।

मुझे लगता है कि यह कारण हो सकता है, यह "==" का उपयोग करते हुए सामान्य तुलना को अस्वीकार करता है।


2
धन्यवाद। मेरा मानना ​​है कि संदर्भ प्रकार ऑपरेटर को भी ओवरराइड कर सकते हैं। लेकिन विफलता का कारण अब स्पष्ट है।
होसम ऐली

1
==टोकन दो अलग-अलग ऑपरेटरों के लिए प्रयोग किया जाता है। यदि दिए गए ऑपरेंड प्रकारों के लिए समानता ऑपरेटर के संगत अधिभार मौजूद है, तो उस अधिभार का उपयोग किया जाएगा। अन्यथा यदि दोनों ऑपरेंड संदर्भ प्रकार हैं जो एक दूसरे के साथ संगत हैं, तो एक संदर्भ तुलना का उपयोग किया जाएगा। ध्यान दें कि Compareसंकलक के ऊपर विधि में यह नहीं बताया जा सकता है कि पहला अर्थ लागू होता है, लेकिन दूसरा अर्थ बता सकता है कि लागू होता है, इसलिए ==टोकन बाद वाले का उपयोग करेगा भले ही Tसमानता-चेक ऑपरेटर को ओवरलोड करता हो (जैसे अगर यह टाइप है String)
सुपरकैट

0

.Equals()मेरे लिए काम करता है, जबकि TKeyएक सामान्य प्रकार है।

public virtual TOutputDto GetOne(TKey id)
{
    var entity =
        _unitOfWork.BaseRepository
            .FindByCondition(x => 
                !x.IsDelete && 
                x.Id.Equals(id))
            .SingleOrDefault();


    // ...
}

वह x.Id.Equalsनहीं id.Equals। संभवतः, संकलक के प्रकार के बारे में कुछ पता है x
होसम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.