2012-11-11 41 views
11

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

पुस्तक के अनुसार, अगर मैं एक Gribulator इकाई है, मैं इस तरह एक comparer बनाने के लिए सक्षम होना चाहिए ...

private class GribulatorComparer : IComparer<Gribulator> { 
    public int Compare(Gribulator g1, Gribulator g2) { 
    return g1.ID.CompareTo(g2.ID); 
    } 
} 

... और फिर इस तरह इसका इस्तेमाल ...

List<Gribulator> distinctGribulators 
    = myGribulators.Distinct(new GribulatorComparer()).ToList(); 

बहरहाल, यह निम्नलिखित संकलक त्रुटियों देता है ...

'System.Collections.Generic.List' 'अलग' और सबसे अच्छा विस्तार विधि अधिभार 'के लिए एक परिभाषा शामिल नहीं है System.Linq.Enumerable .Distinct (System.Collections.Generic.IEnumerable, System.Collections.Generic.IEqualityComparer) 'में कुछ ऐसी अमान्य तर्क हैं

तर्क 2: से परिवर्तित नहीं कर सकते' LinqPlayground.Program.GribulatorComparer System.Collections.Generic.IEqualityComparer 'को' '

मैं थोड़ा के आसपास खोज की है, और है कि इस तरह कोड का उपयोग उदाहरण है, लेकिन संकलक त्रुटियों के बारे में कोई शिकायत नहीं की बहुत देखा है।

मैं क्या गलत कर रहा हूं? इसके अलावा, क्या यह करने का यह सबसे अच्छा तरीका है? मैं यहां एक बंद समाधान चाहता हूं, इसलिए इकाई के लिए कोड को बदलना शुरू नहीं करना चाहते हैं। मैं इकाई को सामान्य के रूप में रखना चाहता हूं, लेकिन केवल एक ही स्थान पर, केवल आईडी द्वारा तुलना करें।

किसी भी मदद के लिए धन्यवाद।

+0

जोड़ने के लिए भूल गए, मैं वीएस2012 का उपयोग कर रहा हूं, और इसलिए .NET 4.0 सी # –

उत्तर

13

आप एक IComparer<T> के रूप में अपने comparer लागू कर रहे हैं, LINQ विधि अधिभार IEqualityComparer के एक कार्यान्वयन की आवश्यकता है:

private class GribulatorComparer : IEqualityComparer<Gribulator> { 
    public bool Equals(Gribulator g1, Gribulator g2) { 
    return g1.ID == g2.ID; 
    } 
} 

संपादित करें:

स्पष्टीकरण के लिए, IComparer इंटरफेस के रूप में, छँटाई के लिए इस्तेमाल किया जा सकता यह मूल रूप से Compare() विधि करता है।

इस तरह

:

items.OrderBy(x => new ItemComparer()); 

private class ItemComparer : IComparer<Item> 
{ 
    public int Compare(Item x, Item y) 
    { 
     return x.Id.CompareTo(y.Id) 
    } 
} 

कौन सा अपने संग्रह को सॉर्ट कि comparer का उपयोग कर जाएगा, हालांकि LINQ कि करने के लिए एक तरीका प्रदान करता है (एक पूर्णांक आईडी की तरह) सरल क्षेत्रों के लिए।

items.OrderBy(x => x.Id); 
+0

धन्यवाद पीटर, यह बताता है! उदाहरण में मैं पुस्तक में उपयोग कर रहा था उदाहरण ऑर्डरबी के लिए था, लेकिन उसने इसे संदर्भित किया जहां से उन्होंने डिस्टिंट पर चर्चा की, और मैंने इस तथ्य पर नहीं उठाया कि मुझे एक अलग इंटरफ़ेस की आवश्यकता है। वास्तव में पुस्तक में बहुत स्पष्ट नहीं था :( –

+0

वैसे, क्या आप जानते हैं कि तुलनात्मक के लिए एक अलग वर्ग बनाने के बजाय, अज्ञात फ़ंक्शन के साथ ऐसा करने का कोई तरीका है? ओवरकिल –

+0

जैसा कि अब तक जैसा कि मुझे पता है, ऐसा नहीं है। मैं वास्तव में इस तरह की चीजों के साथ linq ऑपरेटरों को अधिभारित करने के बारे में सोच रहा हूं। –