[英]C# equality with list-based properties
I've read numerous articles related to proper equality in C#: 我在C#中读过很多与正确相等有关的文章:
http://www.loganfranken.com/blog/687/overriding-equals-in-c-part-1/ http://www.loganfranken.com/blog/687/overriding-equals-in-c-part-1/
What is the best algorithm for an overridden System.Object.GetHashCode? 重写System.Object.GetHashCode的最佳算法是什么?
Assume the following sample class: 假设以下示例类:
public class CustomData
{
public string Name { get; set;}
public IList<double> Values = new List<double>();
}
Would it still be the case to compare the Values property using .Equals() ? 是否仍然需要使用.Equals()来比较Values属性? Here is a full equality sample of what I mean:
这是我的意思的完全相等的样本:
#region Equality
public override bool Equals(object value)
{
if(Object.ReferenceEquals(null, value)) return false; // Is null?
if (Object.ReferenceEquals(this, value)) return true; // Is the same object?
if (value.GetType() != this.GetType()) return false; // Is the same type?
return IsEqual((CustomData)value);
}
public bool Equals(CustomData obj)
{
if (Object.ReferenceEquals(null, obj)) return false; // Is null?
if (Object.ReferenceEquals(this, obj)) return true; // Is the same object?
return IsEqual(obj);
}
private bool IsEqual(CustomData obj)
{
return obj is CustomData other
&& other.Name.Equals(Name)
&& other.Values.Equals(Values);
}
public override int GetHashCode()
{
unchecked
{
// Choose large primes to avoid hashing collisions
const int HashingBase = (int) 2166136261;
const int HashingMultiplier = 16777619;
int hash = HashingBase;
hash = (hash * HashingMultiplier) ^ (!Object.ReferenceEquals(null, Name) ? Name.GetHashCode() : 0);
hash = (hash * HashingMultiplier) ^ (!Object.ReferenceEquals(null, Values) ? Values.GetHashCode() : 0);
return hash;
}
}
public static bool operator ==(CustomData obj, CustomData other)
{
if (Object.ReferenceEquals(obj, other)) return true;
if (Object.ReferenceEquals(null, obj)) return false; // Ensure that "obj" isn't null
return (obj.Equals(other));
}
public static bool operator !=(CustomData obj, CustomData other) => !(obj == other);
#endregion
List<T>.Equals(List<T> other)
will compare references. List<T>.Equals(List<T> other)
将比较引用。 If you want equality for property Values
to be defined as identical sequences of doubles
, use the IEnumerable<TSource>.SequenceEqual.(IEnemerable<TSource> other)
method ( MSDN ). 如果要将属性
Values
相等性定义为相同的doubles
序列,请使用IEnumerable<TSource>.SequenceEqual.(IEnemerable<TSource> other)
方法( MSDN )。 See a refactored version of your IsEqual(CustomData obj)
below: 请参阅下面的
IsEqual(CustomData obj)
的重构版本:
private bool IsEqual(CustomData obj)
{
return obj is CustomData other
&& other.Name.Equals(Name)
&& other.Values.SequenceEqual(Values);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.