比较一个类的两个实例

Sae*_*ani 9 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);
   }   
}
Run Code Online (Sandbox Code Playgroud)

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

Fre*_*els 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;

   }

}
Run Code Online (Sandbox Code Playgroud)

  • +1是一个很好的答案,但请注意"不建议在非不可变类型中覆盖运算符==" - 请参阅http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80)的.aspx (2认同)

Jon*_*Jon 6

一些引用类型的对象T可以通过三种方式相互比较:

  1. 用这个object.Equals方法
  2. 实现IEquatable<T>.Equals(仅适用于实现的类型IEquatable<T>)
  3. 用比较运算符 ==

此外,每种情况都有两种可能性:

  1. 被比较的对象的静态类型是T(或其他一些基础T)
  2. 被比较的对象的静态类型是 object

您绝对需要知道的规则是:

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

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

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

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

你可以看到多态性比较的例子,为什么它可以是一个问题在这里.

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


Pat*_*ald 5

一种实现方法是实施 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
Run Code Online (Sandbox Code Playgroud)

您还可以重写Equals(object)方法(来自System.Object),如果执行此操作,则还应该重写GetHashCode,请参见此处