Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing object used as Key in Dictionary

Tags:

my class:

public class myClass {     public int A { get; set; }     public int B { get; set; }     public int C { get; set; }     public int D { get; set; } } 

and main example:

Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>(); myClass first = new myClass(); first.A = 2; first.B = 3;  myClass second = new myClass(); second.A = 2; second.B = 3; second.C = 5; second.D = 6;  dict.Add(first, new List<string>());  if (dict.ContainsKey(second)) {     //     //should come here and update List<string> for first (and only in this example) key      // } else {     //     //if myFirst object has difference vlues of A or B properties     //     dict.Add(second, new List<string>()); } 

How to do this?

like image 803
Saint Avatar asked Jul 19 '12 14:07

Saint


1 Answers

If you always want the dictionary only to compare on A and B, you have two options. Either use the constructor that implements IEqualityComparer<TKey> and put your comparison logic there, or have your class implement IEquateable<T> GetHashCode and Equals so the default comparer will give you the results you are looking for.

If you only want to compare on A and B in your one situation you will need to use the .Keys property and the Linq extension method Contains that allows you to pass in a IEqualityComparer<T>. However, when doing it this way you loose the speed benefits of using a Dictionary, so use it sparingly.

public class MyClassSpecialComparer : IEqualityComparer<myClass> {     public bool Equals (myClass x, myClass y)     {          return x.A == y.A && x.B == y.B      }      public int GetHashCode(myClass x)     {        return x.A.GetHashCode() + x.B.GetHashCode();     }   }    //Special case for when you only want it to compare this one time  //NOTE: This will be much slower than a normal lookup.     var myClassSpecialComparer = new MyClassSpecialComparer();     Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>();     //(Snip)     if (dict.Keys.Contains(second, myClassSpecialComparer ))     {         //         //should come here and update List<string> for first (and only in this example) key          //     }   //If you want it to always compare     Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>(new MyClassSpecialComparer()); 
like image 73
Scott Chamberlain Avatar answered Oct 03 '22 23:10

Scott Chamberlain