У меня есть MyCustomSet класс с IEquatable , реализованный, как показано ниже.
Это работает fantasti c когда я хочу проверить равенство для всех трех наборов (SetA *, SetB * и Set C*). Но требования диктуют, что мне также необходима возможность проверки равенства только для SetA *, SetB * или Set C* или их комбинации (SetA * и SetB *, SetA * и Set C* или SetB * и Установите C*) и игнорируйте проверку равенства для любого другого набора, который не требуется в проверке.
В настоящее время я использую foreach и LINQ для итерируйте по множествам, чтобы выполнить частичные проверки на равенство, и это работает, но это не очень эффективно для больших наборов данных.
Может быть, ответ смотрит на меня прямо в лицо, но я не вижу это потому, что я понятия не имею, как реализовать 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);
}
}
}
}
* Обновление: *
Спасибо Мэтью Уотсону, который указал мне правильное направление. Поэтому я реализовал пользовательский компаратор следующим образом. Похоже, что это работает, но если кто-то видит потенциальные проблемы или возможности для лучшей реализации, пожалуйста, не стесняйтесь комментировать.
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;
}
}
}