title: How to compare two lists that contain objects that contain Dictionaries?
body: <p>I have two Lists (List “A” and List “B”) that hold objects of type “KeyStore”, which is shown below:</p>
  
  <pre><code>public class KeyStore
  {
      public Dictionary&lt;string, string&gt; PrimaryKeys { get; set; }
  
      public KeyStore(string pkName, string pkValue)
      {
          PrimaryKeys = new Dictionary&lt;string, string&gt; {{pkName, pkValue}};
      }
  
      public KeyStore()
      {
          PrimaryKeys = new Dictionary&lt;string, string&gt;();
      }
  }
  </code></pre>
  
  <p>I need to look at each record in List “A” and see if there is a matching record in List “B”. If there is, then this record needs to be stored in a new list that contains just matching records. A match is considered true if a record’s PrimaryKeys dictionary contains the same number of entries and the same key value combination as a record in List “B”. The order of the entries in the dictionary is not important in testing for equality. If there is a record in List “A” that does not have a match in List “B”, then this needs to be stored in a new list that will only contain records found in List “A”.</p>
  
  <p>Previously I did something similar when I had Lists of strings where I used “Intersect” and “Except” to create lists of matched and non-matched records. I’m assuming that now that I need to compare these KeyStore objects I need to go up a level of complexity. Can anyone offer a solution or advise on how I should approach this problem?</p>
  
  <p>EDIT 1 ----------------</p>
  
  <p>Based on comments, I have created a class that implements IEqualityComparer, as shown below:</p>
  
  <pre><code>class KeyStoreComparer : IEqualityComparer&lt;KeyStore&gt;
  {
      public bool Equals(KeyStore x, KeyStore y)
      {
          if (x != null &amp;&amp; x.PrimaryKeys.Count == y.PrimaryKeys.Count)
          {
              return x.PrimaryKeys.Keys.All(k =&gt; y.PrimaryKeys.ContainsKey(k)) &amp;&amp;
                     x.PrimaryKeys.Keys.All(k =&gt; x.PrimaryKeys[k].Equals(y.PrimaryKeys[k]));
          }
          return false;
      }
  
      public int GetHashCode(KeyStore obj)
      {
          return ReferenceEquals(obj, null) ? 0 : obj.GetHashCode();
      }
  }
  </code></pre>
  
  <p>I have created some dummy data but when the "Intersect" command is run the above code is never called. Any ideas where I am going wrong?</p>
  
  <pre><code>var ListA = new List&lt;KeyStore&gt;();
  ListA.Add(new KeyStore("a", "b"));
  ListA.Add(new KeyStore("c", "d"));
  
  var ListB = new List&lt;KeyStore&gt;();
  ListB.Add(new KeyStore("a", "b"));
  ListB.Add(new KeyStore("x", "y"));
  
  var g = ListA.Intersect(ListB, new KeyStoreComparer());
  </code></pre>
  
  <p>The code in the "Equals" and "GetHashCode" may not be correct but I'm just trying to get it to get as far as running it before I can improve it.</p>
  
  <p>EDIT 2 ---------------------------------------</p>
  
  <p>I have made various changes to the KeyStore class as shown in the example by “fox” on this page. I still don’t get the overridden functions to be called. As an experiment I tried this:</p>
  
  <pre><code>var result = ListA.Equals(ListB);
  </code></pre>
  
  <p>When I do this the overridden functions in the KeyStor class don’t run. But if I do this:</p>
  
  <pre><code>var result = ListA[0].Equals(ListB[0]);
  </code></pre>
  
  <p>The overridden functions do run and give the expected result. Anyone know how I can get this to work for all items in the lists rather than just for individual records?</p>
  
  <p>EDIT 3 ---------------------------------------</p>
  
  <p>The problem I am seeing is that the override works fine for single items, eg:</p>
  
  <pre><code>var a = new KeyStore("a", "b");
  var b = new KeyStore("a", "b");
  var c = a.Equals(b);
  </code></pre>
  
  <p>When I run the above my break point on the KeyStore "Equals" function is hit. As soon as I try to do something similar but with a List of KeyStore, the breakpoint is no longer hit. Do I need to do something extra when working with Lists? </p>