У меня есть класс как это:
public class Foo<T> : IEquatable<T> where T : struct
{
List<T> lst;
[Other irrelevant member stuff]
}
Я хочу реализовать 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));
}
Я получаю эту ошибку:
Error 1 'Foo<T>' does not implement interface member 'System.IEquatable<T>.Equals(T)
Попробуй это.
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);
}
}
К сожалению, List
не переопределяет 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>);
}
Я бы лично очень тщательно подумал перед перегрузкой == и != тоже. Если вы do решили их реализовать, то следует подумать о случаях, когда одно из значений или оба являются нулевыми:
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);
}