两个相同的.NET对象并不是说它们

我有以下代码:

object val1 = 1; object val2 = 1; bool result1 = (val1 == val2);//Equals false bool result2 = val1.Equals(val2); //Equals true 

那是怎么回事? 修复此问题的唯一方法是使用.Equals()方法吗?

operator ==是静态的,而不是虚拟的,因此行为由静态类型而不是运行时类型决定。 对于引用类型的对象, ==默认实现是比较引用(尽管类型可以实现不同的行为,例如string )。 你有两个不同的对象,它们没有相同的引用,所以==返回false。

正如您所指出的,解决方案是使用Equals。 Equals是一种虚拟方法。 由于value1具有运行时类型Int32 ,因此最终调用Int32.Equals 。 从.NET Reflector中可以看到,实现如下:

 public override bool Equals(object obj) { return ((obj is int) && (this == ((int) obj))); } 

换句话说,它检查参数是否为int类型,如果是,则转换它并使用为int定义的== 。 这比较了整数的

修复此问题的唯一方法是使用.Equals()方法吗?

另一种方法是将对象转换为int ,然后使用== ,就像Int32.Equals的实现一样。

是。 ==检查参考相等性。 在要比较内容的位置使用Equals

你可能想知道为什么对象是这样的。 将整数(值类型)设置为对象变量时,会发生称为装箱的操作。 此操作将值类型包装到对象中,并将其放在堆上并返回引用。 这种情况发生两次,引用变得不同(尽管值相同)。

==检查两个对象是否相同 。 他们不是。 它们代表相同的数字,但存储在内存中的不同位置。

这就像比较两个苹果。 两者都是苹果 ,看起来一样,但它们是不同的对象。

这是因为当你将它们转换为对象时,它们会被“转换”为对int值的引用。 而这两个参考文献并不相同。 但是equals比较引用的值而不是引用。

如果您不使用object而是自定义类,则可以覆盖==和!=运算符,并且可能应该实现IEqualityComparer接口

 public static bool operator ==(MyType left, MyType right) { //code here, don't forget about NULLS when writing comparison code!!! } public static bool operator !=(MyType left, MyType right) { return !(left == right); } public bool Equals(MyType x, MyType y) { return (x == y); } public int GetHashCode(MyType obj) { return base.GetHashCode(); } 

如果两个对象指向内存中的相同空间,则它们是相等的。

 val1 == val1; //Equals true 

正如tc所指出的那样,您可以使运算符过载。

 public static bool operator ==(Object a, Object b) 

这样运算符==的行为将是此方法定义的行为。

您还应该重载运算符!=当您重载==

您的代码的CIL将两个整数框进行比较,并比较拳击(==)产生的两个对象。 这种比较是参考。

  .locals init ([0] object val1, [1] object val2, [2] bool result1, [3] bool result2) IL_0000: nop IL_0001: ldc.i4.1 IL_0002: box [mscorlib]System.Int32 IL_0007: stloc.0 IL_0008: ldc.i4.1 IL_0009: box [mscorlib]System.Int32 IL_000e: stloc.1 IL_000f: ldloc.0 IL_0010: ldloc.1 IL_0011: ceq IL_0013: stloc.2 IL_0014: ldloc.0 IL_0015: ldloc.1 IL_0016: callvirt instance bool [mscorlib]System.Object::Equals(object) IL_001b: stloc.3 

对于.Equals,它调用Object.Equals,它调用Int32.Equals(对象上的虚方法调用):

 public override bool Equals(object obj) { return ((obj is int) && (this == ((int) obj))); } 

这将转换为int并将值作为整数进行比较,即值类型比较。