比较对象是否相等 - 如果属性的值相同

compare objects for equality - if the values of the properties are the same

我不经常使用它。所以这就是我问这个问题的原因。

但显然在 C# 中不可能只对对象进行简单的比较。所以当然我先用谷歌搜索,但我只找到了非常多余的解决方案。我知道您可以通过 javascript 序列化对象,然后返回字符串,然后相互比较属性。

因为我只想比较两个简单的对象——如果属性的值相同。所以我有这个:

public class Person
{

    public string FirstName { get; set; }
    public string LastName { get; set; }   


    public Person()
    {
    }

    public bool IsEqualTo(Person compareTo)
    {
        return (FirstName == compareTo.FirstName && LastName == compareTo.LastName);
    }

 public static bool AreEqual<AnyType>(AnyType mass1, AnyType mass2) where AnyType : IComparable<AnyType>
        {
            return mass1.CompareTo(mass2) == 0;
        }


    public Person(string lastName, string firstName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }  
}

但是我不能像这样使用 AreEqual 方法:

var person = new Person("Niels","Engelen");
var person99 = new Person("Niels", "Engelen")

 var equals = Person.AreEqual(person,  person99);

等等:

 var equals = person.CompareTo(person99);

这当然不行

那么只有这个有效吗?

 public bool IsEqualTo(Person compareTo)
    {
        return (FirstName == compareTo.FirstName && LastName == compareTo.LastName);
    }

比输出:

   var equals = person.IsEqualTo(person99);

会是真的。

但是你必须比较每个 属性。

所以没有比较对象的简写方法吗?

谢谢。

很奇怪,在像 C# 这样庞大的语言中,您没有可以比较对象是否相等的方法。

我又搜索了一些,发现你是用记录来做的:

var record1 = new Person.Hello("Niels", "Engelen");
var record2 = new Person.Hello("Niels", "Engelen");

var equalRecords = record1 == record2;
Console.WriteLine("Records " +  equalRecords);

即使在 Javascript 中,您也可以轻松地比较复杂的对象。

实现接口IEquatable<T>然后你就可以使用方法Equals for Person。

 public class Person : IEquatable<Person>
   {

    public string FirstName { get; set; }
    public string LastName { get; set; }


    public Person()
    {
    }

    public bool Equals(Person compareTo)
    {
        return (FirstName == compareTo.FirstName && LastName == compareTo.LastName);
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(FirstName, LastName);
    }

    public Person(string lastName, string firstName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
  }

  var person1 = new Person("test", "test");
  var person2 = new Person("test", "test");
  Assert.AreEqual(person1, person2);
  //true

您还必须重写方法 GetHashCode

假设您使用的是 c#9 或更高版本,您可以简单地将您的类型声明为记录并从开箱即用的编译器中获取基于值的比较:

public record Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

注意:无论您是否切换到记录,您都应该考虑尽可能使您的类型不可变 - 因此将 {get;set;} 更改为 {get;init}{get;} 属性。

如果您使用的是旧版本的 c#,您应该考虑实现 IEquatable<T> 接口。
重要:

If you implement IEquatable, you should also override the base class implementations of Equals(Object) and GetHashCode() so that their behavior is consistent with that of the Equals(T) method. If you do override Equals(Object), your overridden implementation is also called in calls to the static Equals(System.Object, System.Object) method on your class. In addition, you should overload the op_Equality and op_Inequality operators. This ensures that all tests for equality return consistent results.

您可以使用反射循环遍历 class 的所有属性并比较它们:

public bool IsEqualTo(Person other)
    {
        foreach(var prop in typeof(Person).GetProperties())
        {
            var value1 = prop.GetValue(this);
            var value2 = prop.GetValue(other);
            if(!value1.Equals(value2))
            {
                return false;
            }
        }
        return true;
    }

如果添加或删除任何属性,则无需修改 IsEqualTo 方法。这种方法的缺点是反射通常性能不佳。如果你做了很多比较,这可能不是一个好的解决方案。