C# 比较一个类的两个实例

C# 比较一个类的两个实例,c#,class,object,instance,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);

我有一节这样的课

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);
   }   
}
公共类TestData
{
公共字符串名称{get;set;}
公共字符串类型{get;set;}
公共列表成员=新列表();
public void AddMembers(字符串[]成员)
{
Members.AddRange(成员);
}   
}
我想知道是否有可能直接比较这个类的实例,并找出它们完全相同?机制是什么?我正在寻找类似于
if(testData1==testData2)//做点什么
,如果不做,怎么做?

您应该在类上实现接口,它允许您定义相等逻辑。 实际上,您还应该重写
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;

   }

}
公共类测试数据:IEquatable
{
公共字符串名称{get;set;}
公共字符串类型{get;set;}
公共列表成员=新列表();
public void AddMembers(字符串[]成员)
{
Members.AddRange(成员);
}   
//重写Equals成员方法,该方法将调用IEquatable实现
//如果合适的话。
公共覆盖布尔等于(对象对象对象)
{
var other=obj作为测试数据;
if(other==null)返回false;
回报等于(其他);
}
公共覆盖int GetHashCode()
{
//提供自己的实现
}
//这是必须实现的方法,以符合
//可转让合同
公共布尔等于(测试数据其他)
{
如果(其他==null)
{
返回false;
}
if(ReferenceEquals(this,other))
{
返回true;
}
//也可以使用特定的StringComparer而不是EqualityComparer
//查看具体的实现(StringComparer.CurrentCulture,e.a.)。
if(EqualityComparer.Default.Compare(Name,other.Name)==false)
{
返回false;
}
...
//要比较members数组,可以使用
//[SequenceEquals][2]方法。但是,请注意[]{“a”,“b”}不会
//被认为等于[]{“b”,“a”}
返回true;
}
}

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


另请看一看

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


实现
IEquatable接口
。这定义了一个值类型或类实现的通用方法,用于创建用于确定实例相等性的特定于类型的方法。更多信息请点击此处:


一种方法是实现
IEquatable

公共类测试数据:IEquatable
{
公共字符串名称{get;set;}
公共字符串类型{get;set;}
公共列表成员=新列表();
public void AddMembers(字符串[]成员)
{
Members.AddRange(成员);
}
公共布尔等于(测试数据其他)
{
如果(this.Name!=other.Name)返回false;
如果(this.type!=other.type)返回false;
//TODO:比较成员,如果不相同,则返回false
返回true;
}
}
if(testData1.Equals(testData2))
//班级是一样的

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

首先,等式很难定义,只有您可以定义等式对您意味着什么

  • 这是否意味着成员具有相同的值
  • 或者它们指向同一个位置
  • 这里有一个讨论和答案


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

  • 用这个方法
  • 通过实现
    IEquatable.Equals
    (仅适用于实现
    IEquatable
    的类型)
  • 使用比较运算符
    ==
  • 此外,每种情况都有两种可能性:

  • 被比较对象的静态类型为
    T
    (或
    T
    的其他一些基)
  • 被比较对象的静态类型为
    object
  • 你绝对需要知道的规则是:

    • Equals
      operator==
      的默认值都是测试引用相等性
    • 无论比较对象的静态类型是什么,
      Equals
      的实现都将正常工作
    • IEquatable.Equals
      的行为应始终与
      object.Equals
      相同,但如果对象的静态类型为
      T
      ,则它将提供稍好的性能
    那么所有这些在实践中意味着什么呢?

    根据经验,您应该使用
    Equals
    检查相等性(根据需要覆盖
    object.Equals
    ),并实现
    IEquatable
    ,以提供稍好的性能。在这种情况下,
    object.Equals
    应该按照
    IEquatable.Equals
    实现

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

    你可以看到一个多态比较的例子,以及为什么它会成为一个问题


    最后,永远不要忘记,如果您重写
    object.Equals
    ,那么您也必须相应地重写
    object.GetHashCode

    我在这里看到了很多好的答案,但只是为了以防万一您希望比较像这样工作

    if(testData1 == testData2) // DoSomething
    
    您可以重写==和!=操作员:

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

    您也可以使用IComparable,这取决于您的类逻辑以及它是否有意义。+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);
    }