gpt4 book ai didi

c# - 测试对象相等性的最佳方法是什么 - 无需覆盖 Equals 和 GetHashCode,或实现 IEquatable

转载 作者:行者123 更新时间:2023-11-30 19:46:54 26 4
gpt4 key购买 nike

我想检查两个没有公共(public)属性的对象是否相等。但是,我不想覆盖 Equals & GetHashCode 方法,或实现 IEquatable。例如,考虑以下代码:

class Program
{
static void Main(string[] args)
{
Guid id = Guid.NewGuid();
string personName = "MyName";
MyClass object1 = new MyClass(id, personName);
MyClass object2 = new MyClass(id, personName);
//This returns false, but I'd like it to return true:
Console.WriteLine(object1.Equals(object2));
//[edit]...by using, for example:
Console.WriteLine(ObjectsAreEqual(object1, object2));
}
}

class MyClass
{
private Guid _id;
private string _personName;
public MyClass(Guid id, string personName)
{
_id = id;
_personName = personName;
}
}

我知道标准方法是重写 Equals & GetHashCode,但出于各种原因,我不想更改类中的任何代码。另外,没有公共(public)属性(property),所以我无法比较这些。还有其他实现方法吗?

例如,通过反射?或者可能通过将对象序列化为 JSON,然后比较生成的字符串?

谢谢。

最佳答案

您无法更改 Equals 的结果实例方法而不覆盖它。所以你需要使用 IEqualityComparer<T>需要将其显式传递给需要进行相等性检查的代码。幸运的是,大多数内置集合接受这样的相等比较器作为其构造函数的参数。

实现 IEqualityComparer<T>如果您不想以任何方式更改原始类,那么使用反射似乎是您唯一的选择。

您可以获得FieldInfo使用 GetField("_personName",BindingFlags.NonPublic)然后调用GetValue在它上面获取值。

void Main()
{
Guid id = Guid.NewGuid();
string personName = "MyName";
MyClass object1 = new MyClass(id, personName);
MyClass object2 = new MyClass(id, personName);
//This returns false, but I'd like it to return true:
Console.WriteLine(object1.Equals(object2));
//[edit]...by using, for example:
Console.WriteLine(MyClassEqualityComparer.Instance.Equals(object1, object2));
}

public class MyClass
{
private Guid _id;
private string _personName;
public MyClass(Guid id, string personName)
{
_id = id;
_personName = personName;
}
}

public class MyClassEqualityComparer:IEqualityComparer<MyClass>
{
private static FieldInfo personNameField=typeof(MyClass).GetField("_personName",BindingFlags.Instance|BindingFlags.NonPublic);
private static FieldInfo idField=typeof(MyClass).GetField("_id",BindingFlags.Instance|BindingFlags.NonPublic);

public bool Equals(MyClass o1,MyClass o2)
{
if(o1==o2)
return true;
if(o1==null||o2==null)
return false;
string name1=(string)personNameField.GetValue(o1);
string name2=(string)personNameField.GetValue(o2);
if(name1!=name2)
return false;
Guid id1=(Guid)idField.GetValue(o1);
Guid id2=(Guid)idField.GetValue(o2);
return id1==id2;
}

public int GetHashCode(MyClass o)
{
if(o==null)
return 0;
string name=(string)personNameField.GetValue(o);
Guid id=(Guid)idField.GetValue(o);
return name.GetHashCode()^id.GetHashCode();
}

private MyClassEqualityComparer()
{
}

public static readonly IEqualityComparer<MyClass> Instance=new MyClassEqualityComparer();
}

关于c# - 测试对象相等性的最佳方法是什么 - 无需覆盖 Equals 和 GetHashCode,或实现 IEquatable<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7738514/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com