使用IEqualityComparer< T>的推荐最佳做法是什么? [英] What's the recommended best practice for using IEqualityComparer<T>?

查看:127
本文介绍了使用IEqualityComparer< T>的推荐最佳做法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解决方案

我在寻找现实世界的最佳实践,其他人可能已经实施了复杂域的解决方案。时间你考虑使用 IEqualityComparer< T> ,暂停考虑该类是否可以实现 IEquatable< T> 改为。如果产品应始终通过ID进行比较,只需将其定义为等同,以便可以使用默认比较器。



也就是说,仍然有几个原因你可能想要一个自定义的比较器:


  1. 如果有多个方法实例一个类可以被认为是平等的。最好的例子是一个字符串,框架在 StringComparer

  2. 如果类的定义方式不能定义为 IEquatable< T> 。这将包括由其他人定义的类和由编译器生成的类(特别是匿名类型,默认情况下使用属性比较)。

如果你确定需要一个比较器,你一定可以使用一个广义比较器(见DMenT的答案),但如果你需要重用这个逻辑,你应该把它封装在一个专门的类。你甚至可以通过继承泛型基础来声明它:

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

至于使用,你应该尽可能利用comparers。例如,不是在用作字典键的每个字符串(逻辑将散布在您的应用程序中)中调用 ToLower(),您应该声明字典使用不区分大小写 StringComparer 。接受比较器的LINQ运算符也是如此。但同样,总是要考虑是否应该是类的内在而不是外部定义的等价行为。


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

解决方案

Any time you consider using an IEqualityComparer<T>, pause to think if the class could be made to implement IEquatable<T> 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<T>. 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<ShopByProduct>
{
    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.

这篇关于使用IEqualityComparer&lt; T&gt;的推荐最佳做法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆