比较一个类的两个实例

时间:2011-12-06 12:42:39

标签: c# class object instance

我有一个这样的课程

public class TestData
{
   public string Name {get;set;}
   public string type {get;set;}

   public List<string> Members = new List<string>();

   public void AddMembers(string[] members)
   {
      Members.AddRange(members);
   }   
}

我想知道是否可以直接与这个类的实例进行比较,并发现它们完全相同?机制是什么?我正在寻找像if(testData1 == testData2) //Do Something这样的东西,如果没有,怎么办呢?

8 个答案:

答案 0 :(得分:19)

您应该在类上实现IEquatable<T>接口,这样您就可以定义相等逻辑。 实际上,您也应该覆盖Equals方法。

public class TestData : IEquatable<TestData>
{
   public string Name {get;set;}
   public string type {get;set;}

   public List<string> Members = new List<string>();

   public void AddMembers(string[] members)
   {
      Members.AddRange(members);
   }   

  // Overriding Equals member method, which will call the IEquatable implementation
  // if appropriate.

   public override bool Equals( Object obj )
   {
       var other = obj as TestData;
       if( other == null ) return false;

       return Equals (other);             
   }

   public override int GetHashCode()
   {
      // Provide own implementation
   }


   // This is the method that must be implemented to conform to the 
   // IEquatable contract

   public bool Equals( TestData other )
   {
       if( other == null )
       {
            return false;
       }

       if( ReferenceEquals (this, other) )
       {
            return true;
       }

       // You can also use a specific StringComparer instead of EqualityComparer<string>
       // Check out the specific implementations (StringComparer.CurrentCulture, e.a.).
       if( EqualityComparer<string>.Default.Compare (Name, other.Name) == false )
       {
           return false;
       }
       ...

       // To compare the members array, you could perhaps use the 
       // [SequenceEquals][2] method.  But, be aware that [] {"a", "b"} will not
       // be considerd equal as [] {"b", "a"}

       return true;

   }

}

答案 1 :(得分:6)

有三种方法可以将某些引用类型T的对象相互比较:

  1. 使用object.Equals方法
  2. 使用IEquatable<T>.Equals的实现(仅适用于实现IEquatable<T>的类型)
  3. 使用比较运算符==
  4. 此外,每种情况都有两种可能性:

    1. 要比较的对象的静态类型是T(或T的其他基础)
    2. 要比较的对象的静态类型是object
    3. 您绝对需要知道的规则是:

      • Equalsoperator==的默认值是测试引用相等性
      • 无论被比较的对象的静态类型是什么,Equals的实现都将正常工作
      • IEquatable<T>.Equals应始终与object.Equals的行为相同,但如果对象的静态类型为T,则会提供稍好的性能

      那么所有这些在实践中意味着什么呢?

      根据经验,您应该使用Equals检查是否相等(必要时覆盖object.Equals)并实施IEquatable<T>以提供稍好的性能。在这种情况下,object.Equals应根据IEquatable<T>.Equals实施。

      对于某些特定类型(例如System.String),使用operator==也是可以接受的,尽管您必须小心不要进行“多态比较”。另一方面,即使你进行了这样的比较,Equals方法也能正常工作。

      你可以看到一个多态比较的例子以及为什么它可能是一个问题here

      最后,永远不要忘记,如果您覆盖object.Equals,则必须相应地覆盖object.GetHashCode

答案 2 :(得分:4)

实现此目的的一种方法是实施IEquatable<T>

public class TestData : IEquatable<TestData>
{
   public string Name {get;set;}
   public string type {get;set;}

   public List<string> Members = new List<string>();

   public void AddMembers(string[] members)
   {
      Members.AddRange(members);
   }

   public bool Equals(TestData other)
   {
        if (this.Name != other.Name) return false;
        if (this.type != other.type) return false;

        // TODO: Compare Members and return false if not the same

        return true;
   }
}


if (testData1.Equals(testData2))
    // classes are the same

您也可以覆盖Equals(object)方法(来自System.Object),如果这样做,您还应该覆盖GetHashCode see here

答案 3 :(得分:1)

您可以覆盖equals方法,并在其中手动比较对象

另请查看Guidelines for Overloading Equals() and Operator ==

答案 4 :(得分:1)

您需要定义使对象A等于对象B的规则,然后覆盖此类型的Equals运算符。

http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx

答案 5 :(得分:1)

实施IEquatable<T> interface。这定义了一种通用方法,值类型或类实现该方法以创建特定于类型的方法以确定实例的相等性。更多信息:

http://msdn.microsoft.com/en-us/library/ms131187.aspx

答案 6 :(得分:1)

首先,很难确定平等,只有你可以定义平等对你来说意味着什么

  1. 是否意味着会员具有相同的价值
  2. 或者他们指向相同的位置。
  3. 这是一个讨论和答案

    What is "Best Practice" For Comparing Two Instances of a Reference Type?

答案 7 :(得分:1)

我在这里看到了许多不错的答案,但是以防万一您希望比较工作正常

public static bool operator == (TestData left, TestData right)
{
    bool comparison = true; //Make the desired comparison
    return comparison;
}

public static bool operator != (TestData left, TestData right)
{
    return !(left == right);
}

可以使用==和!=运算符代替使用Equals函数:

{{1}}