C#参考说明了对于值类型:
ValueType.Equals(Object)方法将覆盖Object.Equals(Object) 并提供所有值均等的默认实现 .NET Framework中的值类型。
如果当前实例和obj的任何字段均未引用 类型,Equals方法将对两个字节进行逐字节比较 内存中的对象。否则,它会使用反射来比较 obj和此实例的对应字段。
https://msdn.microsoft.com/en-us/library/2dts52z7(v=vs.110).aspx
这样,因为int是一个值类型,所以我希望一个简单的int包装器将等于它包装的int,因为在逐字节比较中它是相同的-它们都只包含一个int :
public struct Id
{
public Id(int id)
{
Id = id;
}
public int Id { get; }
}
Console.WriteLine(new Id(17).Equals(17);
但是它实际上打印为false。为什么会这样?
答案 0 :(得分:3)
这些不是同一类型。尽管文本没有明确说明,但Equals
方法checks属于同一类型。
这将起作用:
new Id(17).Equals(new Id(17));
如果要处理结构上两种不同类型的比较,则需要覆盖Equals
并自己处理。
答案 1 :(得分:2)
public abstract class ValueType {
[System.Security.SecuritySafeCritical]
public override bool Equals (Object obj) {
BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)");
if (null==obj) {
return false;
}
RuntimeType thisType = (RuntimeType)this.GetType();
RuntimeType thatType = (RuntimeType)obj.GetType();
if (thatType!=thisType) {
return false;
}
Object thisObj = (Object)this;
Object thisResult, thatResult;
// if there are no GC references in this object we can avoid reflection
// and do a fast memcmp
if (CanCompareBits(this))
return FastEqualsCheck(thisObj, obj);
FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int i=0; i<thisFields.Length; i++) {
thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
if (thisResult == null) {
if (thatResult != null)
return false;
}
else
if (!thisResult.Equals(thatResult)) {
return false;
}
}
return true;
}
如您所见,它在检查字节之前先验证参数的类型是否匹配。由于您的类型不是int
,因此它将始终返回false。
答案 2 :(得分:0)
通常,即使两个对象都封装相同的值,对象的Equals
方法也不会认为它等于任何其他类型的对象。
由于重载,将某些类型的值传递给其他类型的Equals方法的行为可能导致它们转换为与原始类型相同的类型。例如,(16777216.0f).Equals(16777217)
将选择重载Equals(float)
,将int
值16777217
转换为最接近的float
值(即16777216.0f
),依次比较等于16777216.0f
。如将object
或((object)16777.216.0f).Equals(16777216)
中的任何一个操作数转换为(16777.216.0f).Equals((object)16777216)
,可以防止此行为,其中任何一个都将报告float
对象与{{1} }对象(即使它们具有相同的数值)。