测试对象相等性的最佳方法是什么 - 不覆盖 Equals & GetHashCode,或实现 IEquatable?
我想检查两个没有公共属性的对象之间是否相等。但是,我不想覆盖 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,但由于各种原因,我不想更改类中的任何代码。另外,没有公共属性,所以我无法比较它们。还有其他方法可以实现吗?
例如,通过反射?或者也许通过将对象序列化为 JSON,然后比较结果字符串?
谢谢。
I'd like to check for equality among two objects that have no Public Properties. However, I don't want to override the Equals & GetHashCode method, or implement IEquatable. For example, consider the following code:
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;
}
}
I know the standard method is to override Equals & GetHashCode, but for various reasons, I don't want to change any code in the class. Plus, there are no public properties, so I can't compare these. Is there any other way of implementing this?
For example, via reflection? Or perhaps by serialising the Objects to JSON, and comparing the resulting strings?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您无法在不重写
Equals
实例方法的情况下更改它的结果。因此,您需要使用IEqualityComparer
,它需要显式传递给需要相等检查的代码。幸运的是,大多数内置集合接受这样的相等比较器作为其构造函数的参数。如果您不想以任何方式更改原始类,那么使用反射实现 IEqualityComparer似乎是您唯一的选择。
您可以使用
GetField("_personName",BindingFlags.NonPublic)
获取FieldInfo
,然后对其调用GetValue
来获取值。You can't change the result of the
Equals
instance method without overriding it. So you'll need to useIEqualityComparer<T>
which needs to be passed explicitly to the code that requires equality checks. Luckily most built in collections accept such an equality comparer as a parameter to their constructor.Implementing
IEqualityComparer<T>
with reflection seems to be your only option if you don't want to change the original class in any way.You can get the
FieldInfo
usingGetField("_personName",BindingFlags.NonPublic)
and then callGetValue
on it to get the value.您可以创建自定义
IEqualityComparer
使用反射的实现:You could create a custom
IEqualityComparer<T>
implementation that uses reflection:您可以向 MyClass 添加一个成员函数并检查其中的私有字段:
或者如果您无法更改 MyClass 实现,则添加扩展方法,并使用反射进行比较,如 CodeInChaos 所描述的:
You could add a member function to MyClass and check the private fields there:
or add extension method if you can't change the MyClass implementation, and compare using reflection as CodeInChaos described: