<p>I would like to compare the contents of a couple of collections in my Equals method.  I have a Dictionary and an IList.  Is there a built-in method to do this?</p>

<p>Edited:
I want to compare two Dictionaries and two ILists, so I think what equality means is clear - if the two dictionaries contain the same keys mapped to the same values, then they're equal.</p>

[{'answer_id': 43501, 'author': 'Mark Ingram', 'author_id': 986, 'author_profile': 'https://Stackoverflow.com/users/986', 'pm_score': 0, 'selected': False, 'text': '<p>No, because the framework doesn\'t know how to compare the contents of your lists.</p>\n\n<p>Have a look at this:</p>\n\n<p><a href="http://blogs.msdn.com/abhinaba/archive/2005/10/11/479537.aspx" rel="nofollow noreferrer">http://blogs.msdn.com/abhinaba/archive/2005/10/11/479537.aspx</a></p>\n'}, {'answer_id': 43505, 'author': 'Glenn Slaven', 'author_id': 2975, 'author_profile': 'https://Stackoverflow.com/users/2975', 'pm_score': 9, 'selected': True, 'text': '<p><a href="http://msdn.microsoft.com/en-us/library/bb342073.aspx" rel="noreferrer"><code>Enumerable.SequenceEqual</code></a></p>\n\n<blockquote>\n  <p>Determines whether two sequences are equal by comparing their elements by using a specified IEqualityComparer(T).</p>\n</blockquote>\n\n<p>You can\'t directly compare the list &amp; the dictionary, but you could compare the list of values from the Dictionary with the list</p>\n'}, {'answer_id': 43506, 'author': 'aku', 'author_id': 1196, 'author_profile': 'https://Stackoverflow.com/users/1196', 'pm_score': 3, 'selected': False, 'text': '<p>Take a look at the <a href="http://msdn.microsoft.com/en-us/library/bb348567.aspx" rel="noreferrer">Enumerable.SequenceEqual</a>  method</p>\n\n<pre><code>var dictionary = new Dictionary&lt;int, string&gt;() {{1, "a"}, {2, "b"}};\nvar intList = new List&lt;int&gt; {1, 2};\nvar stringList = new List&lt;string&gt; {"a", "b"};\nvar test1 = dictionary.Keys.SequenceEqual(intList);\nvar test2 = dictionary.Values.SequenceEqual(stringList);\n</code></pre>\n'}, {'answer_id': 43518, 'author': 'Giovanni Galbo', 'author_id': 4050, 'author_profile': 'https://Stackoverflow.com/users/4050', 'pm_score': 2, 'selected': False, 'text': "<p>I didn't know about Enumerable.SequenceEqual method (you learn something every day....), but I was going to suggest using an extension method; something like this:</p>\n\n<pre><code>    public static bool IsEqual(this List&lt;int&gt; InternalList, List&lt;int&gt; ExternalList)\n    {\n        if (InternalList.Count != ExternalList.Count)\n        {\n            return false;\n        }\n        else\n        {\n            for (int i = 0; i &lt; InternalList.Count; i++)\n            {\n                if (InternalList[i] != ExternalList[i])\n                    return false;\n            }\n        }\n\n        return true;\n\n    }\n</code></pre>\n\n<p>Interestingly enough, after taking 2 seconds to read about SequenceEqual, it looks like Microsoft has built the function I described for you.</p>\n"}, {'answer_id': 2740552, 'author': 'user329244', 'author_id': 329244, 'author_profile': 'https://Stackoverflow.com/users/329244', 'pm_score': 2, 'selected': False, 'text': '<p>.NET Lacks any powerful tools for comparing collections. I\'ve developed a simple solution you can find at the link below:</p>\n\n<p><a href="http://robertbouillon.com/2010/04/29/comparing-collections-in-net/" rel="nofollow noreferrer">http://robertbouillon.com/2010/04/29/comparing-collections-in-net/</a></p>\n\n<p>This will perform an equality comparison regardless of order:</p>\n\n<pre><code>var list1 = new[] { "Bill", "Bob", "Sally" };\nvar list2 = new[] { "Bob", "Bill", "Sally" };\nbool isequal = list1.Compare(list2).IsSame;\n</code></pre>\n\n<p>This will check to see if items were added / removed:</p>\n\n<pre><code>var list1 = new[] { "Billy", "Bob" };\nvar list2 = new[] { "Bob", "Sally" };\nvar diff = list1.Compare(list2);\nvar onlyinlist1 = diff.Removed; //Billy\nvar onlyinlist2 = diff.Added;   //Sally\nvar inbothlists = diff.Equal;   //Bob\n</code></pre>\n\n<p>This will see what items in the dictionary changed:</p>\n\n<pre><code>var original = new Dictionary&lt;int, string&gt;() { { 1, "a" }, { 2, "b" } };\nvar changed = new Dictionary&lt;int, string&gt;() { { 1, "aaa" }, { 2, "b" } };\nvar diff = original.Compare(changed, (x, y) =&gt; x.Value == y.Value, (x, y) =&gt; x.Value == y.Value);\nforeach (var item in diff.Different)\n  Console.Write("{0} changed to {1}", item.Key.Value, item.Value.Value);\n//Will output: a changed to aaa\n</code></pre>\n'}, {'answer_id': 4655702, 'author': 'Allon Guralnek', 'author_id': 149265, 'author_profile': 'https://Stackoverflow.com/users/149265', 'pm_score': 6, 'selected': False, 'text': '<p>As others have suggested and have noted, <code>SequenceEqual</code> is order-sensitive. To solve that, you can sort the dictionary by key (which is unique, and thus the sort is always stable) and then use <code>SequenceEqual</code>. The following expression checks if two dictionaries are equal regardless of their internal order:</p>\n\n<pre><code>dictionary1.OrderBy(kvp =&gt; kvp.Key).SequenceEqual(dictionary2.OrderBy(kvp =&gt; kvp.Key))\n</code></pre>\n\n<hr>\n\n<p><strong>EDIT:</strong> As pointed out by Jeppe Stig Nielsen, some object have an <code>IComparer&lt;T&gt;</code> that is incompatible with their <code>IEqualityComparer&lt;T&gt;</code>, yielding incorrect results. When using keys with such an object, you must specify a correct <code>IComparer&lt;T&gt;</code> for those keys. For example, with string keys (which exhibit this issue), you must do the following in order to get correct results:</p>\n\n<pre><code>dictionary1.OrderBy(kvp =&gt; kvp.Key, StringComparer.Ordinal).SequenceEqual(dictionary2.OrderBy(kvp =&gt; kvp.Key, StringComparer.Ordinal))\n</code></pre>\n'}, {'answer_id': 9348579, 'author': 'Desty', 'author_id': 664033, 'author_profile': 'https://Stackoverflow.com/users/664033', 'pm_score': 4, 'selected': False, 'text': '<p>In addition to the mentioned <a href="http://msdn.microsoft.com/en-us/library/bb342073.aspx" rel="noreferrer">SequenceEqual</a>, which </p>\n\n<blockquote>\n  <p>is true if two lists are of equal length and their corresponding\n  elements compare equal according to a comparer</p>\n</blockquote>\n\n<p>(which may be the default comparer, i.e. an overriden <code>Equals()</code>)</p>\n\n<p>it is worth mentioning that in .Net4 there is <a href="http://msdn.microsoft.com/en-us/library/dd412096.aspx" rel="noreferrer">SetEquals</a> on <code>ISet</code> objects, \nwhich</p>\n\n<blockquote>\n  <p>ignores the order of elements and any duplicate elements.</p>\n</blockquote>\n\n<p>So if you want to have a list of objects, but they don\'t need to be in a specific order, consider that an <code>ISet</code> (like a <code>HashSet</code>) may be the right choice.</p>\n'}, {'answer_id': 12470106, 'author': 'tymtam', 'author_id': 581076, 'author_profile': 'https://Stackoverflow.com/users/581076', 'pm_score': 3, 'selected': False, 'text': "<p>This is not directly answering your questions, but both the MS' TestTools and NUnit provide </p>\n\n<pre><code> CollectionAssert.AreEquivalent\n</code></pre>\n\n<p>which does pretty much what you want. </p>\n"}, {'answer_id': 35963754, 'author': 'mbadeveloper', 'author_id': 3752193, 'author_profile': 'https://Stackoverflow.com/users/3752193', 'pm_score': 0, 'selected': False, 'text': '<pre><code>public bool CompareStringLists(List&lt;string&gt; list1, List&lt;string&gt; list2)\n{\n    if (list1.Count != list2.Count) return false;\n\n    foreach(string item in list1)\n    {\n        if (!list2.Contains(item)) return false;\n    }\n\n    return true;\n}\n</code></pre>\n'}, {'answer_id': 39720054, 'author': 'Chrono', 'author_id': 1649245, 'author_profile': 'https://Stackoverflow.com/users/1649245', 'pm_score': 1, 'selected': False, 'text': '<p>To compare collections you can also use LINQ. <a href="https://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect" rel="nofollow"><code>Enumerable.Intersect</code></a> returns all pairs that are equal. You can comparse two dictionaries like this:</p>\n\n<pre><code>(dict1.Count == dict2.Count) &amp;&amp; dict1.Intersect(dict2).Count() == dict1.Count\n</code></pre>\n\n<p>The first comparison is needed because <code>dict2</code> can contain all the keys from <code>dict1</code> and more.</p>\n\n<p>You can also use think of variations using <a href="https://msdn.microsoft.com/en-us/library/system.linq.enumerable.except" rel="nofollow"><code>Enumerable.Except</code></a> and <a href="https://msdn.microsoft.com/en-us/library/system.linq.enumerable.union" rel="nofollow"><code>Enumerable.Union</code></a> that lead to similar results. But can be used to determine the exact differences between sets.</p>\n'}, {'answer_id': 43353457, 'author': 'ispostback', 'author_id': 5893015, 'author_profile': 'https://Stackoverflow.com/users/5893015', 'pm_score': 1, 'selected': False, 'text': '<p>How about this example: </p>\n\n<pre><code> static void Main()\n{\n    // Create a dictionary and add several elements to it.\n    var dict = new Dictionary&lt;string, int&gt;();\n    dict.Add("cat", 2);\n    dict.Add("dog", 3);\n    dict.Add("x", 4);\n\n    // Create another dictionary.\n    var dict2 = new Dictionary&lt;string, int&gt;();\n    dict2.Add("cat", 2);\n    dict2.Add("dog", 3);\n    dict2.Add("x", 4);\n\n    // Test for equality.\n    bool equal = false;\n    if (dict.Count == dict2.Count) // Require equal count.\n    {\n        equal = true;\n        foreach (var pair in dict)\n        {\n            int value;\n            if (dict2.TryGetValue(pair.Key, out value))\n            {\n                // Require value be equal.\n                if (value != pair.Value)\n                {\n                    equal = false;\n                    break;\n                }\n            }\n            else\n            {\n                // Require key be present.\n                equal = false;\n                break;\n            }\n        }\n    }\n    Console.WriteLine(equal);\n}\n</code></pre>\n\n<p>Courtesy :  <a href="https://www.dotnetperls.com/dictionary-equals" rel="nofollow noreferrer">https://www.dotnetperls.com/dictionary-equals</a></p>\n'}, {'answer_id': 50775030, 'author': 'Ken Kin', 'author_id': 927012, 'author_profile': 'https://Stackoverflow.com/users/927012', 'pm_score': 0, 'selected': False, 'text': '<p>There wasn\'t, isn\'t and might not be, at least I would believe so. The reason behind is collection equality is probably an user defined behavior. </p>\n\n<p>Elements in collections are not supposed to be in a particular order though they do have an ordering naturally, it\'s not what the comparing algorithms should rely on. Say you have two collections of: </p>\n\n<pre><code>{1, 2, 3, 4}\n{4, 3, 2, 1}\n</code></pre>\n\n<p>Are they equal or not? You must know but I don\'t know what\'s your point of view. </p>\n\n<p>Collections are conceptually unordered by default, until the algorithms provide the sorting rules. The same thing SQL server will bring to your attention is when you trying to do pagination, it requires you to provide sorting rules: </p>\n\n<p><a href="https://learn.microsoft.com/en-US/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017" rel="nofollow noreferrer">https://learn.microsoft.com/en-US/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017</a></p>\n\n<p>Yet another two collections: </p>\n\n<pre><code>{1, 2, 3, 4}\n{1, 1, 1, 2, 2, 3, 4}\n</code></pre>\n\n<p>Again, are they equal or not? You tell me .. </p>\n\n<p>Element repeatability of a collection plays its role in different scenarios and some collections like <code>Dictionary&lt;TKey, TValue&gt;</code> don\'t even allow repeated elements. </p>\n\n<p>I believe these kinds of equality are application defined and the framework therefore did not provide all of the possible implementations. </p>\n\n<p>Well, in general cases <code>Enumerable.SequenceEqual</code> is good enough but it returns false in the following case: </p>\n\n<pre><code>var a = new Dictionary&lt;String, int&gt; { { "2", 2 }, { "1", 1 }, };\nvar b = new Dictionary&lt;String, int&gt; { { "1", 1 }, { "2", 2 }, };\nDebug.Print("{0}", a.SequenceEqual(b)); // false\n</code></pre>\n\n<p>I read some answers to questions like this(you may <a href="https://www.google.com/search?biw=884&amp;bih=1256&amp;ei=4NYbW7isOobl0gS-lLTwAQ&amp;q=c%20sharp%20equality%20collection%20site%3Astackoverflow.com&amp;oq=c%20sharp%20equality%20collection%20site%3Astackoverflow.com&amp;gs_l=psy-ab.12...0.0.0.15542.0.0.0.0.0.0.0.0..0.0....0...1c..64.psy-ab..0.0.0....0.PIjsswnuGsU" rel="nofollow noreferrer">google</a> for them) and what I would use, in general: </p>\n\n<pre><code>public static class CollectionExtensions {\n    public static bool Represents&lt;T&gt;(this IEnumerable&lt;T&gt; first, IEnumerable&lt;T&gt; second) {\n        if(object.ReferenceEquals(first, second)) {\n            return true;\n        }\n\n        if(first is IOrderedEnumerable&lt;T&gt; &amp;&amp; second is IOrderedEnumerable&lt;T&gt;) {\n            return Enumerable.SequenceEqual(first, second);\n        }\n\n        if(first is ICollection&lt;T&gt; &amp;&amp; second is ICollection&lt;T&gt;) {\n            if(first.Count()!=second.Count()) {\n                return false;\n            }\n        }\n\n        first=first.OrderBy(x =&gt; x.GetHashCode());\n        second=second.OrderBy(x =&gt; x.GetHashCode());\n        return CollectionExtensions.Represents(first, second);\n    }\n}\n</code></pre>\n\n<p>That means one collection represents the other in their elements including repeated times without taking the original ordering into account. Some notes of the implementation: </p>\n\n<ul>\n<li><p><code>GetHashCode()</code> is just for the ordering not for equality; I think it\'s enough in this case</p></li>\n<li><p><code>Count()</code> will not really enumerates the collection and directly fall into the property implementation of <code>ICollection&lt;T&gt;.Count</code></p></li>\n<li><p>If the references are equal, it\'s just Boris</p></li>\n</ul>\n'}, {'answer_id': 51903573, 'author': 'kofifus', 'author_id': 460084, 'author_profile': 'https://Stackoverflow.com/users/460084', 'pm_score': 1, 'selected': False, 'text': '<p>For ordered collections (List, Array) use <code>SequenceEqual</code></p>\n\n<p>for HashSet use <code>SetEquals</code></p>\n\n<p>for Dictionary you can do:</p>\n\n<pre><code>namespace System.Collections.Generic {\n  public static class ExtensionMethods {\n    public static bool DictionaryEquals&lt;TKey, TValue&gt;(this IReadOnlyDictionary&lt;TKey, TValue&gt; d1, IReadOnlyDictionary&lt;TKey, TValue&gt; d2) {\n      if (object.ReferenceEquals(d1, d2)) return true; \n      if (d2 is null || d1.Count != d2.Count) return false;\n      foreach (var (d1key, d1value) in d1) {\n        if (!d2.TryGetValue(d1key, out TValue d2value)) return false;\n        if (!d1value.Equals(d2value)) return false;\n      }\n      return true;\n    }\n  }\n}\n</code></pre>\n\n<p>(A more optimized solution will use sorting but that will require <code>IComparable&lt;TValue&gt;</code>)</p>\n'}, {'answer_id': 63476151, 'author': 'Denis535', 'author_id': 4805491, 'author_profile': 'https://Stackoverflow.com/users/4805491', 'pm_score': 0, 'selected': False, 'text': "<p>I've made my own compare method. It returns common, missing, and extra values.</p>\n<pre><code>private static void Compare&lt;T&gt;(IEnumerable&lt;T&gt; actual, IEnumerable&lt;T&gt; expected, out IList&lt;T&gt; common, out IList&lt;T&gt; missing, out IList&lt;T&gt; extra) {\n    common = new List&lt;T&gt;();\n    missing = new List&lt;T&gt;();\n    extra = new List&lt;T&gt;();\n\n    var expected_ = new LinkedList&lt;T&gt;( expected );\n    foreach (var item in actual) {\n        if (expected_.Remove( item )) {\n            common.Add( item );\n        } else {\n            extra.Add( item );\n        }\n    }\n    foreach (var item in expected_) {\n        missing.Add( item );\n    }\n}\n</code></pre>\n"}, {'answer_id': 71462170, 'author': 'ErroneousFatality', 'author_id': 1445435, 'author_profile': 'https://Stackoverflow.com/users/1445435', 'pm_score': 0, 'selected': False, 'text': "<h2>Comparing dictionaries' contents:</h2>\n<p>To compare two <code>Dictionary&lt;K, V&gt;</code> objects, we can assume that the keys are unique for every value, thus if two sets of keys are equal, then the two dictionaries' contents are equal.</p>\n<pre><code>Dictionary&lt;K, V&gt; dictionaryA, dictionaryB;\nbool areDictionaryContentsEqual = new HashSet&lt;K&gt;(dictionaryA.Keys).SetEquals(dictionaryB.Keys);\n</code></pre>\n<hr />\n<h2>Comparing collections' contents:</h2>\n<p>To compare two <code>ICollection&lt;T&gt;</code> objects, we need to check:</p>\n<ol>\n<li>If they are of the same length.</li>\n<li>If every <code>T</code> value that appears in the first collection appears an equal number of times in the second.</li>\n</ol>\n<pre><code>public static bool AreCollectionContentsEqual&lt;T&gt;(ICollection&lt;T&gt; collectionA, ICollection&lt;T&gt; collectionB)\n    where T : notnull\n{\n    if (collectionA.Count != collectionB.Count)\n    {\n        return false;\n    }\n    Dictionary&lt;T, int&gt; countByValueDictionary = new(collectionA.Count);\n    foreach(T item in collectionA)\n    {\n        countByValueDictionary[item] = countByValueDictionary.TryGetValue(item, out int count) \n            ? count + 1 \n            : 1;\n    }\n    foreach (T item in collectionB)\n    {\n        if (!countByValueDictionary.TryGetValue(item, out int count) || count &lt; 1)\n        {\n            return false;\n        }\n        countByValueDictionary[item] = count - 1;\n    }\n    return true;\n}\n</code></pre>\n<hr />\n<p>These solutions should be optimal since their time and memory complexities are <code>O(n)</code>, while the solutions that use ordering/sorting have time and memory complexities greater than <code>O(n)</code>.</p>\n"}]
['https://Stackoverflow.com/questions/43500', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2348/']