Chr*_*ris 5 c# generics interface
我有一个这样的课:
public class Foo<T> : IEquatable<T> where T : struct
{
List<T> lst;
[Other irrelevant member stuff]
}
Run Code Online (Sandbox Code Playgroud)
我想实现IEquatable<T>Foo类的接口.我需要做什么.为简单起见,我想检查列表成员是否相等.
谢谢.
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));
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
Error 1 'Foo<T>' does not implement interface member 'System.IEquatable<T>.Equals(T)
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 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>);
}
Run Code Online (Sandbox Code Playgroud)
在重载==和!=之前我个人会仔细考虑.如果你做决定执行它们,你应该想想情况下值的一个或两个是空:
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);
}
Run Code Online (Sandbox Code Playgroud)
尝试这个。
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);
}
}
Run Code Online (Sandbox Code Playgroud)