2011-08-12 11 views
17

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

ऐसा लगता है कि यह इस उदाहरण के साथ काम कर रहा है, लेकिन वास्तविक वर्ग में कई अन्य गुण हैं और मुझे कुछ अन्य वर्गों के साथ भी ऐसा करने की आवश्यकता है।

तो मैं सोच रहा था कि क्या मैं पहिया का पुन: आविष्कार कर रहा हूं?

क्या दो वस्तुओं के सभी गुणों की तुलना करने का कोई आसान तरीका है? फिलहाल, मुझे वास्तव में केवल सामान्य प्रकार वाले वर्ग से निपटने की आवश्यकता है, लेकिन यह अच्छा होगा कि मेरे पास एक तुलनात्मक है जो कक्षाओं के साथ काम करता है जिसमें अन्य वर्गों के उदाहरण होते हैं।

void Main() 
{ 
    var t1 = new Sizes { Name = "Test" , Size = 1} ; 
    var t2 = new Sizes { Name = "Test" , Size = 1} ; 

    var list1 = new List<Sizes>(); 
    var list2 = new List<Sizes>(); 
    list1.Add(t1); 
    list2.Add(t2); 

    var differences = list2.Except(list1 , new SizesComparer());  
    // differences should be empty. 
} 


public class Sizes 
{ 
    public string Name { get; set; } 
    public int Size { get; set; } 
} 

public class SizesComparer : IEqualityComparer<Sizes> 
{ 
    bool IEqualityComparer<Sizes>.Equals(Sizes x, Sizes y) 
    {    
     return (x.Name.Equals(y.Name) && x.Size.Equals(y.Size));   
    } 

    int IEqualityComparer<Sizes>.GetHashCode(Sizes obj) 
    { 
     if (Object.ReferenceEquals(obj, null)) 
      return 0;    

     return obj.Name.GetHashCode() + obj.Size;  
    } 
} 
+1

देखें IEnumerable.Except() और एक कस्टम comparer - http://stackoverflow.com/q/1299513/485076 – sll

उत्तर

4

समाधान जो मैं का उपयोग कर के रूप में तेजी से नहीं कहा जा सकता है समाप्त हो गया है, लेकिन यह मेरा एक चिंता का विषय नहीं है और यह है कि मैं क्या चाहता हूँ यह हो सकता है कि करता है पुन: उपयोग किया जाता है और किसी भी विशेष वर्ग तक ही सीमित नहीं है।

यह स्ट्रिंग पर ऑब्जेक्ट को क्रमबद्ध करने के लिए न्यूटॉन्सॉफ्ट.जेसन लाइब्रेरी का उपयोग करता है और फिर परिणाम की तुलना करता है। यह अज्ञात वर्गों और घोंसले वर्गों के साथ काम करने का भी लाभ उठाता है।

मुझे लगता है कि तुलनात्मक तरीके से यह है कि यह पहली बार गेटहाशकोड को दोनों ऑब्जेक्ट्स पर कॉल करता है और यदि वे इससे मेल खाते हैं तो वे बराबर कहते हैं, जो इस दिनचर्या में मतलब होगा कि मिलान करने वाली वस्तुओं को दो बार क्रमबद्ध किया जाएगा।

public class JSonEqualityComparer<T> : IEqualityComparer<T> 
{ 
    public bool Equals(T x, T y) 
    {   
     return String.Equals 
     ( 
      Newtonsoft.Json.JsonConvert.SerializeObject(x), 
      Newtonsoft.Json.JsonConvert.SerializeObject(y) 
     );     
    } 

    public int GetHashCode(T obj) 
    {       
     return Newtonsoft.Json.JsonConvert.SerializeObject(obj).GetHashCode();   
    }    
}  


public static partial class LinqExtensions 
{ 
    public static IEnumerable<T> ExceptUsingJSonCompare<T> 
     (this IEnumerable<T> first, IEnumerable<T> second) 
    { 
     return first.Except(second, new JSonEqualityComparer<T>()); 
    } 
} 

इसका इस्तेमाल करने के लिए आप ExceptUsingJSonCompare साथ छोड़कर स्वैप, उदाहरण के लिए:

var differences = list2.ExceptUsingJSonCompare(list1); 
0

सबसे अच्छा तरीका है मैं आमतौर पर के लिए जाना प्रत्येक में अद्वितीय/संयुक्त कुंजी objectand कि जिस तरह से आप केवल महत्वपूर्ण हिस्सा तुलना और न है अन्य बिट्स तुलना करने के लिए है की कोशिश है।

आप प्रतिबिंब का उपयोग कर सकते हैं जो वर्ग की प्रत्येक सार्वजनिक संपत्ति (जो बहुत सामान्य होगा) के माध्यम से जाएगा और उनकी तुलना करें, लेकिन यह धीमा हो जाएगा।

32

आप की तरह कुछ की कोशिश कर सकते:

var differences = list2.Where(l2 => 
    !list1.Any(l1 => l1.Name == l2.Name && l1.Size == l2.Size)); 
+0

यदि आप एक ही प्रकार से सूचियों में ऑब्जेक्ट्स जोड़ते हैं तो यह पूरी तरह से काम करता है। –

+1

धन्यवाद। IEqualityComparer का उपयोग करने से अधिक संक्षेप में – garyh

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