2010-01-17 31 views
5

我有一类这样的:C#实现IEquatable <T> .Equal <T>

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) 

回答

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); 
     } 


    } 
+1

感谢。我需要IEquatable 而不是IEquatable 。我知道这是愚蠢的。 – Chris 2010-01-17 08:28:44

+4

这是行不通的 - List.Equals没有做到你想要的。 – 2010-01-17 08:34:10

+0

感谢您的纠正。修改原始帖子。 – 2010-01-17 10:01:02

12

不幸的是,List<T>不会覆盖EqualsGetHashCode。这意味着,即使你已经纠正你的类声明,你就需要自己进行比较:

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>); 
} 

我个人觉得非常仔细地超载之前==和=呢!如果您决定执行它们,你应该想想情况下,一方或双方的价值观为空:

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); 
} 
+0

谢谢!我想知道你如何克服'两个值都是空'的情况。 object.ReferenceEquals()是答案。谢谢! – 2010-08-25 02:49:37

+0

像往常一样感谢。好帖子! – Dienekes 2011-02-11 07:27:44

相关问题