<p>I'm looking for real world best practices, how other people might have implemented solutions with complex domains.</p>

[{'answer_id': 74070, 'author': 'Eric Schoonover', 'author_id': 3957, 'author_profile': 'https://Stackoverflow.com/users/3957', 'pm_score': 2, 'selected': False, 'text': '<p>This is what <a href="http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx" rel="nofollow noreferrer">MSDN</a> has to say about IEqualityComparer (non-generic):</p>\n<blockquote>\n<p>This interface allows the implementation of customized equality comparison for collections. That is, you can create your own definition of equality, and specify that this definition be used with a collection type that accepts the <code>IEqualityComparer</code> interface. In the .NET Framework, constructors of the <code>Hashtable</code>, <code>NameValueCollection</code>, and <code>OrderedDictionary</code> collection types accept this interface.</p>\n<p>This interface supports only equality comparisons. Customization of comparisons for sorting and ordering is provided by the <code>IComparer</code> interface.</p>\n</blockquote>\n<p>It looks like the generic version of this interface performs the same function but is used for <code>Dictionary&lt;(Of &lt;(TKey, TValue&gt;)&gt;)</code> collections.</p>\n<p>As far as best practices around using this interface for your own purposes.  I would say that the best practice would be to use it when you are deriving or implementing a class that has similar functionality to the above mentioned .NET framework collections and where you want to add the same capability to your own collections.  This will ensure that you are consistent with how the .NET framework uses the interface.</p>\n<p>In other words support the use of this interface if you are developing a custom collection and you want to allow your consumers to control equality which is used in a number of LINQ and collection related methods (eg. Sort).</p>\n'}, {'answer_id': 74110, 'author': 'Chris Marasti-Georg', 'author_id': 96, 'author_profile': 'https://Stackoverflow.com/users/96', 'pm_score': 1, 'selected': False, 'text': '<p>I would say that the best use would be when you need to plug in different equality rules for a certain algorithm.  Much in the same way that a sorting algorithm might accept an <code>IComparer&lt;T&gt;</code>, a finding algorithm might accept an <code>IEqualityComparer&lt;T&gt;</code></p>\n'}, {'answer_id': 74125, 'author': 'Jesper Blad Jensen', 'author_id': 11559, 'author_profile': 'https://Stackoverflow.com/users/11559', 'pm_score': 1, 'selected': False, 'text': "<p>The list uses this interface alot, so you can say a.Substract(b) or other of these nice functions.</p>\n\n<p>Just remember: If you're objects don't return the same Hashcode, the Equals is not called.</p>\n"}, {'answer_id': 533826, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 3, 'selected': False, 'text': '<p>I did the following, I\'m not sure if it is real-world best practice, but it worked fine for me. :)</p>\n\n<pre><code>public class GenericEqualityComparer&lt;T&gt; : IEqualityComparer&lt;T&gt;\n{\n    private Func&lt;T, T, Boolean&gt; _comparer;\n    private Func&lt;T, int&gt; _hashCodeEvaluator;\n    public GenericEqualityComparer(Func&lt;T, T, Boolean&gt; comparer)\n    {\n        _comparer = comparer;\n    }\n\n    public GenericEqualityComparer(Func&lt;T, T, Boolean&gt; comparer, Func&lt;T, int&gt; hashCodeEvaluator)\n    {\n        _comparer = comparer;\n        _hashCodeEvaluator = hashCodeEvaluator;\n    }\n\n    #region IEqualityComparer&lt;T&gt; Members\n\n    public bool Equals(T x, T y)\n    {\n        return _comparer(x, y);\n    }\n\n    public int GetHashCode(T obj)\n    {\n        if(obj == null) {\n            throw new ArgumentNullException("obj");\n        }\n        if(_hashCodeEvaluator == null) {\n            return 0;\n        } \n        return _hashCodeEvaluator(obj);\n    }\n\n    #endregion\n}\n</code></pre>\n\n<p>Then you can use it in your collections.</p>\n\n<pre><code>var comparer = new GenericEqualityComparer&lt;ShopByProduct&gt;((x, y) =&gt; x.ProductId == y.ProductId);\nvar current = SelectAll().Where(p =&gt; p.ShopByGroup == group).ToList();\nvar toDelete = current.Except(products, comparer);\nvar toAdd = products.Except(current, comparer);\n</code></pre>\n\n<p>If you need to support custom GetHashCode() functionality, use the alternative constructor to provide a lambda to do the alternative calculation:</p>\n\n<pre><code>var comparer = new GenericEqualityComparer&lt;ShopByProduct&gt;(\n       (x, y) =&gt; { return x.ProductId == y.ProductId; }, \n       (x)    =&gt; { return x.Product.GetHashCode()}\n);\n</code></pre>\n\n<p>I hope this helps. =)</p>\n'}, {'answer_id': 1535426, 'author': 'dahlbyk', 'author_id': 54249, 'author_profile': 'https://Stackoverflow.com/users/54249', 'pm_score': 4, 'selected': False, 'text': '<p>Any time you consider using an <code>IEqualityComparer&lt;T&gt;</code>, pause to think if the class could be made to implement <code>IEquatable&lt;T&gt;</code> instead. If a <code>Product</code> should always be compared by ID, just define it to be equated as such so you can use the default comparer.</p>\n\n<p>That said, there are still a few of reasons you might want a custom comparer:</p>\n\n<ol>\n<li>If there are multiple ways instances of a class could be considered equal. The best example of this is a string, for which the framework provides six different comparers in <a href="http://msdn.microsoft.com/en-us/library/system.stringcomparer.aspx" rel="noreferrer"><code>StringComparer</code></a>.</li>\n<li>If the class is defined in such a way that you can\'t define it as <code>IEquatable&lt;T&gt;</code>. This would include classes defined by others and classes generated by the compiler (specifically anonymous types, which use a property-wise comparison by default).</li>\n</ol>\n\n<p>If you do decide you need a comparer, you can certainly use a generalized comparer (see DMenT\'s answer), but if you need to reuse that logic you should encapsulate it in a dedicated class. You could even declare it by inheriting from the generic base:</p>\n\n<pre><code>class ProductByIdComparer : GenericEqualityComparer&lt;ShopByProduct&gt;\n{\n    public ProductByIdComparer()\n        : base((x, y) =&gt; x.ProductId == y.ProductId, z =&gt; z.ProductId)\n    { }\n}\n</code></pre>\n\n<p>As far as use, you should take advantage of comparers when possible. For example, rather than calling <code>ToLower()</code> on every string used as a dictionary key (logic for which will be strewn across your app), you should declare the dictionary to use a case-insensitive <code>StringComparer</code>. The same goes for the LINQ operators that accept a comparer. But again, always consider if the equatable behavior that should be intrinsic to the class rather than defined externally.</p>\n'}, {'answer_id': 4679491, 'author': 'Peet Brits', 'author_id': 371917, 'author_profile': 'https://Stackoverflow.com/users/371917', 'pm_score': 3, 'selected': False, 'text': '<p>See this post for (better) alternatives: <a href="https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer">Wrap a delegate in an IEqualityComparer</a></p>\n\n<p>Scroll down to the part on <a href="https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer/1239337#1239337">KeyEqualityComparer</a> and especially the part on <a href="https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer/3719802#3719802">the importance of GetHashCode</a>. There is a whole <a href="https://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer/3719617#3719617">discussion</a> on why <code>obj.GetHashCode();</code> (as suggested by DMenT\'s post) is wrong and should just return 0 instead.</p>\n'}]
['https://Stackoverflow.com/questions/74032', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5802/']