What's the recommended best practice for using IEqualityComparer
|
1 2 3 4 5 6 | class ProductByIdComparer : GenericEqualityComparer<ShopByProduct> { public ProductByIdComparer() : base((x, y) => x.ProductId == y.ProductId, z => z.ProductId) { } } |
就使用而言,应尽可能利用比较器。例如,您应该声明字典使用不区分大小写的
我做了以下事情,我不确定这是否是现实世界中的最佳实践,但对我来说效果很好。 :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public class GenericEqualityComparer< T > : IEqualityComparer< T > { private Func<T, T, Boolean> _comparer; private Func<T, int> _hashCodeEvaluator; public GenericEqualityComparer(Func<T, T, Boolean> comparer) { _comparer = comparer; } public GenericEqualityComparer(Func<T, T, Boolean> comparer, Func<T, int> hashCodeEvaluator) { _comparer = comparer; _hashCodeEvaluator = hashCodeEvaluator; } #region IEqualityComparer< T > Members public bool Equals(T x, T y) { return _comparer(x, y); } public int GetHashCode(T obj) { if(obj == null) { throw new ArgumentNullException("obj"); } if(_hashCodeEvaluator == null) { return 0; } return _hashCodeEvaluator(obj); } #endregion } |
然后,您可以在收藏夹中使用它。
1 2 3 4 | var comparer = new GenericEqualityComparer<ShopByProduct>((x, y) => x.ProductId == y.ProductId); var current = SelectAll().Where(p => p.ShopByGroup == group).ToList(); var toDelete = current.Except(products, comparer); var toAdd = products.Except(current, comparer); |
如果需要支持自定义GetHashCode()功能,请使用替代构造函数提供一个lambda来进行替代计算:
1 2 3 4 | var comparer = new GenericEqualityComparer<ShopByProduct>( (x, y) => { return x.ProductId == y.ProductId; }, (x) => { return x.Product.GetHashCode()} ); |
我希望这有帮助。 =)
请参阅此帖子以了解(更好的)替代方法:将委托包装在IEqualityComparer中
向下滚动到KeyEqualityComparer上的部分,尤其是有关GetHashCode重要性的部分。关于
这是MSDN关于IEqualityComparer(非泛型)所说的:
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
IEqualityComparer interface. In the .NET Framework, constructors of theHashtable ,NameValueCollection , andOrderedDictionary collection types accept this interface.This interface supports only equality comparisons. Customization of comparisons for sorting and ordering is provided by the
IComparer interface.
看起来该接口的通用版本执行相同的功能,但用于
关于围绕此接口用于您自己的目的的最佳实践。我会说,最佳实践是在派生或实现具有与上述.NET Framework集合相似的功能的类,并且希望在自己的集合中添加相同功能的类时使用它。这将确保您与.NET框架使用接口的方式保持一致。
换句话说,如果您正在开发自定义集合,并且希望允许您的使用者控制在许多LINQ和与集合相关的方法(例如,排序)中使用的相等性,则支持使用此接口。
该列表大量使用此接口,因此您可以说a.Substract(b)或其他一些不错的函数。
只需记住:如果您的对象没有返回相同的哈希码,则不会调用Equals。
我会说最好的用法是当您需要为某个算法插入不同的相等规则时。排序算法可以接受