我有一个这样的课程:
public class Foo<T> : IEquatable<T> where T : struct
{
List<T> lst;
[Other irrelevant member stuff]
}
我想为Foo类实现IEquatable<T>
接口。我需要做什么。为简单起见,我想检查列表成员是否相等。
感谢。
C#4.0支持的答案是允许的。
更新:这是我目前拥有的:
public bool Equals(Foo<T> foo)
{
return lst.Equals(foo.lst);
}
public override bool Equals(Object obj)
{
if (obj == null) return base.Equals(obj);
if (!(obj is Foo<T>))
{
throw new Exception("The 'obj' argument is not a Foo<T> object.");
}
else
{
return Equals(obj as Foo<T>)
}
}
public override int GetHashCode()
{
return this.lst.GetHashCode();
}
public static bool operator ==(Foo<T> f1, Foo<T> f2)
{
return f1.Equals(f2);
}
public static bool operator !=(Foo<T> f1, Foo<T> f2)
{
return (!f1.Equals(f2));
}
我收到此错误:
Error 1 'Foo<T>' does not implement interface member 'System.IEquatable<T>.Equals(T)
答案 0 :(得分:12)
很遗憾,List<T>
不会覆盖Equals
或GetHashCode
。这意味着即使你已经更正了你的课堂声明,你也需要自己进行比较:
public bool Equals(Foo<T> foo)
{
// These need to be calls to ReferenceEquals if you are overloading ==
if (foo == null)
{
return false;
}
if (foo == this)
{
return true;
}
// I'll assume the lists can never be null
if (lst.Count != foo.lst.Count)
{
return false;
}
for (int i = 0; i < lst.Count; i++)
{
if (!lst[i].Equals(foo.lst[i]))
{
return false;
}
}
return true;
}
public override int GetHashCode()
{
int hash = 17;
foreach (T item in lst)
{
hash = hash * 31 + item.GetHashCode();
}
return hash;
}
public override bool Equals(Object obj)
{
// Note that Equals *shouldn't* throw an exception when compared
// with an object of the wrong type
return Equals(obj as Foo<T>);
}
在重载==和!=之前我个人会仔细考虑。如果你做决定实现它们,你应该考虑其中一个或两个值为null的情况:
public static bool operator ==(Foo<T> f1, Foo<T> f2)
{
if (object.ReferenceEquals(f1, f2))
{
return true;
}
if (object.ReferenceEquals(f1, null)) // f2=null is covered by Equals
{
return false;
}
return f1.Equals(f2);
}
答案 1 :(得分:2)
试试这个。
public class Foo<T> : IEquatable<Foo<T>> where T : struct
{
List<T> lst;
#region IEquatable<T> Members
public bool Equals(Foo<T> other)
{
if (lst.Count != other.lst.Count)
{
return false;
}
for (int i = 0; i < lst.Count; i++)
{
if (!lst[i].Equals(other.lst[i]))
{
return false;
}
}
return true;
}
#endregion
public override bool Equals(object obj)
{
var other = obj as Foo<T>;
return other != null && Equals(other);
}
}