What's the recommended best practice for using IEqualityComparer?

前端 未结 6 1102
栀梦
栀梦 2020-12-30 09:33

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

6条回答
  •  误落风尘
    2020-12-30 09:53

    Any time you consider using an IEqualityComparer, pause to think if the class could be made to implement IEquatable instead. If a Product should always be compared by ID, just define it to be equated as such so you can use the default comparer.

    That said, there are still a few of reasons you might want a custom comparer:

    1. 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 StringComparer.
    2. If the class is defined in such a way that you can't define it as IEquatable. This would include classes defined by others and classes generated by the compiler (specifically anonymous types, which use a property-wise comparison by default).

    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:

    class ProductByIdComparer : GenericEqualityComparer
    {
        public ProductByIdComparer()
            : base((x, y) => x.ProductId == y.ProductId, z => z.ProductId)
        { }
    }
    

    As far as use, you should take advantage of comparers when possible. For example, rather than calling ToLower() 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 StringComparer. 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.

提交回复
热议问题