如何使用不同的相等性检查实现IEquatable

问题描述 投票:0回答:1

我有一个实现为[[IEquatableMyCustomSet类,如下所示。

当我要检查所有三个集合(SetA *,SetB *和SetC *)的相等性时,此效果很好。但要求表明,我还需要仅检查SetA *,SetB *或SetC *或其组合(SetA *和SetB *,SetA *和SetC *或SetB *和SetC *)的相等性并忽略检查的能力检查中不需要的任何其他Set的相等性。

当前,我正在使用

foreach

和LINQ遍历Sets以执行部分​​相等性检查,并且可以,但是对于大型数据集而言,这似乎不是很有效。也许答案是直面我的脸,但我没有看到它,因为我不知道如何实现

IEquatable

来处理不同的相等性检查。有人会协助我提供一些建议或指导,以指导如何实施吗?一个例子将更加令人赞赏。

public static class HashCode { public const int Start = 17; public static int Hash<T>(this int hash, T obj) { var h = EqualityComparer<T>.Default.GetHashCode(obj); return unchecked((hash * 439) + h); } } public class MyCustomSetModel { public sealed class MyCustomSet : IEquatable<MyCustomSet> { public string ItemName { get; set; } public string ItemType { get; set; } public double SetA1 { get; set; } public double SetA2 { get; set; } public double SetA3 { get; set; } public double SetB1 { get; set; } public double SetB2 { get; set; } public double SetB3 { get; set; } public double SetC1 { get; set; } public double SetC2 { get; set; } public double SetC3 { get; set; } public bool Equals(MyCustomSet other) { if (ReferenceEquals(other, null)) { return false; } if (ReferenceEquals(other, this)) { return true; } return ( (this.ItemName == other.ItemName) && (this.ItemType == other.ItemType) && (this.SetA1 == other.SetA1) && (this.SetA2 == other.SetA2) && (this.SetA3 == other.SetA3) && (this.SetB1 == other.SetB1) && (this.SetB2 == other.SetB2) && (this.SetB3 == other.SetB3) && (this.SetC1 == other.SetC1) && (this.SetC2 == other.SetC2) && (this.SetC3 == other.SetC3) ); } public override bool Equals(object obj) => Equals(obj as MyCustomSet); public override int GetHashCode() { unchecked { return HashCode.Start .Hash(ItemName) .Hash(ItemType) .Hash(SetA1) .Hash(SetA2) .Hash(SetA3) .Hash(SetB1) .Hash(SetB2) .Hash(SetB3) .Hash(SetC1) .Hash(SetC2) .Hash(SetC3); } } } }

*更新:*

感谢Matthew Watson向我指出了正确的方向。因此,我实现了一个自定义比较器,如下所示。看来它正在运行,但是如果有人看到潜在的问题或有更好的实施空间,请随时发表评论。

public sealed class MyCustomSetComparer : IEqualityComparer<MyCustomSet> { private bool _compareSetA; private bool _compareSetB; private bool _compareSetC; public MyCustomSetComparer(bool compareSetA = true, bool compareSetB = true, bool compareSetC = true) { _compareSetA = compareSetA; _compareSetB = compareSetB; _compareSetC = compareSetC; } public bool Equals(MyCustomSet x, MyCustomSet y) { if (Object.ReferenceEquals(x, y)) { return true; } if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) { return false; } bool result = (x.ItemName == y.ItemName) && (x.ItemType == y.ItemType); if (_compareSetA) { result = result && (x.SetA1 == y.SetA1) && (x.SetA2 == y.SetA2) && (x.SetA3 == y.SetA3); } if (_compareSetB) { result = result && (x.SetB1 == y.SetB1) && (x.SetB2 == y.SetB2) && (x.SetB3 == y.SetB3); } if (_compareSetC) { result = result && (x.SetC1 == y.SetC1) && (x.SetC2 == y.SetC2) && (x.SetC3 == y.SetC3); } return result; } public int GetHashCode(MyCustomSet item) { if (Object.ReferenceEquals(item, null)) { return 0; } int hash = HashCode.Start .Hash(item.ItemName) .Hash(item.ItemType); if (_compareSetA) { hash = hash.Hash(item.SetA1) .Hash(item.SetA2) .Hash(item.SetA3); } if (_compareSetB) { hash = hash.Hash(item.SetB1) .Hash(item.SetB2) .Hash(item.SetB3); } if (_compareSetC) { hash = hash.Hash(item.SetC1) .Hash(item.SetC2) .Hash(item.SetC3); } unchecked { return hash; } } }

c# equality iequalitycomparer iequatable
1个回答
0
投票
根据Matthew Watson的评论,这是使用IEqualityComparer<T>而不是IEqualityComparer<T>的完美时机。我建议仅在对类型的相等性有一个显而易见的自然定义时才实施IEquatable<T>。当存在多个相等选项时,没有一个选项比其他选项更合理时,请以几种不同的实现类型或以创建为参数的单个实现类型来实现IEquatable<T>
© www.soinside.com 2019 - 2024. All rights reserved.