问题描述
我需要检查对象(不是所有属性),对于原始类型,一切都可以正常工作,但是对于对象类型,方法Object.Equals(object a,object b)
返回错误的结果。
public static bool IsModified<T>(T newProp,T oldProp) where T : class
{
List<string> IgnoreProps = new List<string> { "UpdatedOn","UpdatedById","UpdatedBy","RowVersion" };
Type type = typeof(T);
foreach(PropertyInfo prop in type.GetProperties())
{
if (IgnoreProps.Contains(prop.Name))
{
continue;
}
var propType = prop.PropertyType;
var newValue = prop.GetValue(newProp);
var oldValue = prop.GetValue(oldProp);
newValue = Convert.ChangeType(newValue,propType);
oldValue = Convert.ChangeType(oldValue,propType);
var a = Equals(newValue,oldValue); // return incorrect value
if (!Equals(newValue,oldValue))
{
return true;
}
}
return false;
}
第一个对象
第二个对象
解决方法
Equals的默认实现支持 引用类型,以及值类型的按位相等性。参考 相等意味着比较的对象引用引用了 同一对象。按位相等意味着被比较的对象具有 相同的二进制表示形式。 (https://docs.microsoft.com/en-us/dotnet/api/system.object.equals?redirectedfrom=MSDN&view=netcore-3.1)
由于您有两个不同的引用(var newValue
,var oldValue
),因此您得到false
。
考虑您有一个MyCustomClass
类和以下示例:
class MyCustomClass
{
public string txt;
}
static void Main(string[] args)
{
MyCustomClass cl1 = new MyCustomClass()
{
txt = "a"
};
MyCustomClass cl2 = new MyCustomClass()
{
txt = "a"
};
if (Equals(cl1,cl2))
Console.WriteLine("equal");
else
Console.WriteLine("NOT equal");
}
如果运行上面的代码,您将获得输出NOT equal
。这是因为.net将尝试仅比较该类的2个实例之间的引用。例如,如果您写:
if (Equals(cl1,cl1))
Console.WriteLine("equal");
else
Console.WriteLine("NOT equal");
当您将同一实例equal
与cl1
进行比较时,将得出cl1
。
对于您来说,为了与Equals方法进行比较,您将不得不在类中覆盖它。例如,您的班级应该变成:
class MyCustomClass
{
public string txt;
public override bool Equals(object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || !this.GetType().Equals(obj.GetType()))
{
return false;
}
else
{
MyCustomClass p = (MyCustomClass)obj;
return (txt == p.txt);
}
}
}
上面的Equals
方法,不仅可以确保比较的对象是not null
,而且可以确保same type
的对象是public class Person {
String name;
String gender;
public static void main(String[] args) {
Person person = new Person();
person.name("Max");
person.gender = "male";
Person person2 = new Person();
person2.name = "Lea";
person2.gender = "female";
}
,而且还可以确保它们一一比较。