2012-02-14 15 views
9

System.Collections.Generic से सूची वर्ग के साथ काम करते समय, युक्त या इंडेक्सऑफ जैसी विधियां आईक्वाटेबल से लागू समानता विधि या ऑब्जेक्ट क्लास द्वारा प्रदान की गई ओवरराइड समान विधि का उपयोग करके पारित संदर्भ के ऑब्जेक्ट की तुलना करेंगी। यदि ऑब्जेक्ट। एक्वाल्स ओवरराइड नहीं है, तो यह जांच करेगा कि पारित संदर्भ उसी ऑब्जेक्ट को स्वयं के रूप में इंगित करता है या नहीं।संदर्भ से तुलना करें?

मेरा प्रश्न है: यदि बराबर ओवरराइड किया गया है तो संदर्भ द्वारा सूची तुलना करने का कोई तरीका है? कोड नीचे दी गई सूची से आइटम निकाल देंगे:

class Program 
{ 
    static void Main(string[] args) 
    {  
     var s1 = new SomeClass() { A = 5 }; 
     var s2 = new SomeClass() { A = 5 }; 
     var list = new List<SomeClass>(); 
     list.Add(s1); 
     list.Remove(s2); // s1 will get removed, even though s2 has been 
         // passed, because s1's Equals method will return true. 

    } 
} 

class SomeClass 
{ 
    public int A { get; set; } 

    public override bool Equals(object obj) 
    { 
     SomeClass s = obj as SomeClass; 
     if (s == null) 
     { 
      return false; 
     } 
     else 
     { 
      return s.A == this.A; 
     } 
    } 
} 

मान लीजिए कि मैं बराबर की SomeClass 'कार्यान्वयन को दूर करने में असमर्थ हूँ चलो, वहाँ के बजाय संदर्भ मूल्य से तुलना सूची बनाने का एक तरीका है?

उत्तर

13

आप List.RemoveAll का उपयोग कर सकते हैं और अपने अनुमान में, Object.ReferenceEquals के साथ आइटम की तुलना करें।

list.RemoveAll(item => object.ReferenceEquals(item, s2)); 

विजुअल स्टूडियो 2010 एक्सप्रेस से डिबगिंग करते समय कोड ने 1 आइटम सफलतापूर्वक हटा दिया।

+0

धन्यवाद, ऐसा लगता है कि यह ठीक काम करता है। – haiyyu

4

ऑस्टिन का समाधान सरल और काम है। लेकिन यहां दो सामान्य विस्तार विधियां भी हैं:

items.RemoveAllByReference(item); 

public static void RemoveAllByReference<T>(this List<T> list, T item) 
{ 
    list.RemoveAll(x=> object.ReferenceEquals(x, item)); 
} 

public static bool RemoveFirstByReference<T>(this List<T> list, T item) 
{ 
    var index = -1; 
    for(int i = 0; i< list.Count; i++) 
     if(object.ReferenceEquals(list[i], item)) 
     { 
      index = i; 
      break; 
     } 
    if(index == -1) 
     return false; 

    list.RemoveAt(index); 
    return true; 
} 
+0

दिलचस्प लेकिन यह अधिक इष्टतम क्यों है - क्या यह आंतरिक रूप से भविष्यवाणी के समान नहीं है? बस अपने तर्क को जानना पसंद है ... –

+0

क्या आइटम सूची में एन बार है? –

+0

ऑस्टिन की विधि हमेशा सभी तत्वों की जांच करती है। जब यह एक पाता है तो यह लूप को तोड़ देता है। लेकिन अब जब मैं इसके बारे में सोचता हूं, तो पूरी सूची को खोजने और सूची में एक ही आइटम के सभी उदाहरणों को हटाने के लिए और अधिक सही हो सकता है ... तो यह आपके इच्छित चीज़ों पर निर्भर करता है। लेकिन फिर भी, यदि आप इसे कई स्थानों पर उपयोग करते हैं तो एक विस्तार विधि एक लाभ है। – doblak