【发布时间】:2009-12-04 00:33:24
【问题描述】:
我正在尝试使用反射来确定在一个类型的两个不同但“相等”的实例上调用 .Equals 的结果。
我的方法是这样的:
public static bool TypeComparesProperties(Type t)
{
// return true if (an instance of t).Equals(a different instance of t)
// will be true if all publicly accessible properties of the instances
// are the same
}
举例:
string a = "Test";
string b = "Test";
bool areEqual = a.Equals(b); // areEqual will be true
// so:
TypeComparesProperties(typeof(string)); // should return true
但是,鉴于:
public class MyComplexType
{
public int Id { get; set; }
public string MyString { get; set; }
}
MyComplexType a = new MyComplexType {Id = 1, MyString = "Test"};
MyComplexType b = new MyComplexType { Id = 1, MyString = "Test" };
bool areEqual = a.Equals(b); // areEqual will be false
// so:
TypeComparesProperties(typeof(MyComplexType)); // should return false
如果我按如下方式在我的班级上实现IEquatable<MyComplexType>,我会得到正确的:
public class MyComplexType : IEquatable<MyComplexType>
{
public int Id { get; set; }
public string MyString { get; set; }
public bool Equals(MyComplexType other)
{
return (Id.Equals(other.Id) && MyString.Equals(other.MyString));
}
}
我想我可以通过使用反射实例化两个实例来实现,然后将所有属性设置为适当类型的默认值。虽然这需要大量工作和大量开销,而且我认为如果该类型上没有空构造函数,我会遇到问题。
还有其他想法吗?
编辑:
似乎人们对我的意图感到困惑。我道歉。希望这会澄清:
我有一个方法可以最大程度地比较两个对象。简单地调用 .Equals() 是不够的,因为:
- 这些对象将是值类型或将以一种很好的方式实现 IEquatable,我会得到一个真实的响应。太好了!
- 对象可能具有所有相同的属性并且是“相等的”,但由于它们是不同的实例,我会得到错误的响应。 我不知道这是因为对象不“相等”,还是因为它们只是不同的实例。
所以在我看来,比较方法应该是:
- 检查对象类型以查看其
Equals方法是否会为具有相同公共属性的两个不同实例返回true。 - 如果是,调用
Equals方法并返回结果 - 如果不是,请查看所有属性和字段并尽可能比较它们以确定它们是否相等
现在,我知道我可以直接跳到第 3 步,但如果有办法提前确定是否有必要,那将节省时间。
编辑 2:
我要关闭它有几个原因:
- 我越是谈论它,我就越意识到我问的并不是我真正想做的事情
- 即使我确实想这样做,也没有真正的捷径可走。 RE 之前的编辑,无论如何我都应该跳到第 3 步。
感谢大家的意见。
【问题讨论】:
-
这个问题相当于The Halting Problem;一般无法解决。你能解释一下为什么要这样做吗?
-
RE 停止问题,您的意思是如果我要在每个属性上递归调用此方法以寻找相等性?否则我看不出它是如何等价的......
-
在回答您的问题时,基本上是尝试确定给定类型是否“简单”到足以使用 .Equals 进行比较。我从相对不同的系统(共享类型程序集)接收两个对象,我想尽我所能比较它们。如果我不能使用 Equals,我想检查属性并尽力进行比较。
-
您实际上想在这里完成什么?这将有助于确定如何解决这个问题。
-
我不确定你试图对空构造函数等做出什么意义......你能澄清你的意思吗?
标签: c# reflection comparison equality