2010-12-02 17 views
37

क्या यह सी # में अज्ञात प्रकारों की दो वस्तुओं की तुलना करने के लिए संभव है, (संदर्भ और मूल्य प्रकार दोनों सहित) उनके प्रकार तुलनाकर्ताओं का उपयोग करते हुए यदि वे मौजूद हैं?सी # अज्ञात प्रकारों (संदर्भ और मूल्य प्रकार सहित) की दो वस्तुओं की तुलना करें

लक्ष्य एक समारोह है कि इस तरह एक हस्ताक्षर करना होगा लिखना है:

public bool Compare(object a, object b) 
{ 
    // compare logic goes here 
} 

कौन सा वापसी होगी

Compare(100d, 100d) == true 
Compare(100f, 100f) == true 
Compare("hello", "hello") == true 
Compare(null, null) == true 
Compare(100d, 101d) == false 
Compare(100f, null) == false 

// Use type comparators where possible, i.e.: 
Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 01)) == true 
Compare(new DateTime(2010, 12, 01), new DateTime(2010, 12, 02)) == false 
Compare(new DateTime(2010, 12, 01), null) == false 

इस समस्या यह है कि किसी के लिए काम करेगा हल करने के लिए एक सामान्य दृष्टिकोण है वस्तु का प्रकार?

उत्तर

59

आप स्थिर object.Equals(object x, object y) विधि का उपयोग कर सकते हैं और पूरी तरह से अपना विधि लिख परेशान नहीं दे। यह उचित रूप से नल को संभालेगा, और या y से जुड़े object.Equals(object) के कार्यान्वयन के लिए प्रतिनिधि होगा ... नहीं होना चाहिए, जैसा कि Equals सममित होना है।

नोट इस नहीं किसी भी प्रकार के लिए == ऑपरेटरों का उपयोग करता है कि - ऑपरेटरों, ओवरराइड नहीं किया जा सकता है केवल अतिभारित (जिसका अर्थ है वे संकलन समय, नहीं निष्पादन समय पर चुना रहे अधिकांश मामलों में Equals आपको जो चाहिए वो करना चाहिए। कुछ मामलों में, == को ओवरलोड नहीं किया जा सकता है, भले ही Equals ओवरराइड हो गया है ... लेकिन मैंने कभी भी किसी भी प्रकार के काम के साथ उलटा होने के विपरीत नहीं जाना है।

ध्यान दें कि इस दृष्टिकोण होगा बॉक्स किसी भी मूल्य प्रकार ...

का उपयोग कर

संपादित करें: प्रभावी ढंग से पुन: कार्यान्वयन के बारे में हटाया गया अनुभाग - खराब - EqualityComparer<T>.Default। अधिक के लिए मार्क का जवाब देखें। यह आपकी मदद नहीं करेगा यदि आप सामान्य प्रकार का सामान्य उपयोग नहीं कर सकते हैं।

एक अंतिम बिंदु: मैं अपने विधि Compare फोन नहीं हैं । वह नाम आमतौर पर से मानों को समानता के लिए तुलना करने के बजाय आदेशित करता है।

+0

+1: इस के लिए अच्छा स्पष्टीकरण – TalentTuner

+1

+1 और श्री स्कीट द्वारा कई अन्य उत्तरों के लिए +1। धन्यवाद! –

+0

निश्चित रूप से बाद के केवल संदर्भ के प्रकार के लिए काम के रूप में आप 'जहां टी होनी चाहिए होगा:' v1 == null' तो रोकने मान प्रकार तुलना क्रम में class' उपयोग करने के लिए। – aqwert

0

क्या

if (a == null && b == null) return true; 
if (a == null && b != null) return false; 
return (a.equals(b)); 

के बारे में?

5

कैसे object.equals(x, y)? यह शून्य मूल्यों को भी स्वीकार करेगा।

-2

मैं 100% यकीन है कि अगर यह सभी मामलों में काम करता है नहीं कर रहा हूँ, लेकिन यह एक कोशिश

 
public bool Compare(object a, object b) 
{ 
    return a.Equals(b); 
} 
+1

यह शून्य होने पर एक NullReferenceException का कारण बन जाएगा। – Zeemee

20

एक उचित विकल्प है, जेनरिक के साथ काम करने के लिए है अर्थात

public bool Compare<T>(T a, T b) {...} 

आप अपने कोड में T निर्दिष्ट करने के लिए के रूप में संकलक आमतौर पर यह पता लगाने में सक्षम हो जाएगा की जरूरत नहीं होगी (अर्थातअपने मौजूदा नमूने काम करेगा "के रूप में-है")

कार्यान्वयन के लिए:

bool equal = EqualityComparer<T>.Default.Equals(x, y); 

(सामान्य प्रकार T) के लिए

लेकिन वास्तव में के रूप में वह यह है कि मैं, शब्द Compare से बच जाएंगे अन्यत्र इस्तेमाल </==/> मतलब करने के लिए - तो मैं हो सकता है:

public static bool Equals<T>(T a, T b) { 
    return EqualityComparer<T>.Default.Equals(a, b); 
} 

यह:

  • मुक्केबाजी से बचा जाता है जब टी एक struct
  • nulls संभालती है/Nullable<T> सही ढंग से
  • IEquatable<T>
  • का समर्थन करता है या नियमित रूप से Equals

करने के लिए वापस गिर जाता है यह नहीं करता है == ऑपरेटर का उपयोग करें, लेकिन MiscUtil में एक है Operator वर्ग कि होगा, के माध्यम से

bool equal = Operator.Equal<T>(x,y); 

(यह बाद ध्यान दें, हालांकि इस बारे में सोच है, यह एक fallback के रूप में इस्तेमाल कर सकते हैं EqualityComparer<T>.Default.Equals, अगर T एक == ऑपरेटर नहीं है असफल हो जायेगी; यह सिर्फ ऐसा नहीं करता)


पूर्णता के लिए, ध्यान दें कि Comparer<T>.Default.Compare(x,y) तुलना संचालन संभालती है।

+1

उत्कृष्ट उत्तर के लिए धन्यवाद, आपके और जॉन स्कीट के उत्तर दोनों मेरे विशेष उपयोग के मामले के लिए काम करते हैं। – Duane

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