简体   繁体   English

对于CLR类型,Object.Equals(objA,objB),objA.Equals(objB)和objA == objB之间的区别?

[英]Difference between Object.Equals(objA, objB), objA.Equals(objB) and objA == objB for CLR types?

I am wondering if the CLR types would return different results from the following: 我想知道CLR类型是否会返回以下不同的结果:

Object.Equals(objA, objB)

objA.Equals(objB)

(objA == objB)

I do realize that outside of the CLR someone could easily implement the IEqualtable Equals and overload the == operator improperly. 我确实意识到在CLR之外有人可以轻松地实现IEqualtable Equals并且不正确地重载==运算符。 I'm not concerned with people improperly implementing these. 我不关心那些不正当地实施这些的人。 What I'm concerened with is the classes (including String, Int32, etc) implement these 3 differently. 我所关注的是类(包括String,Int32等)以不同的方式实现这3个。

Also, which one should be the one used for comparison overall (across the board) if that is possible. 此外,如果可能的话,哪一个应该是用于整体比较的(全面)。 I wonder this because I ran across a file that uses Object.Equals(objA, objB) all over a view-model instead of the other two. 我想知道这是因为我在整个视图模型而不是其他两个文件中运行了一个使用Object.Equals(objA, objB)的文件。

private string _name;
public string Name
{
    get { return _name; }
    set
    {
        if (Equals(_name, value)) return;
        ...
    }
}

private int _id;
public int Id
{
    get { return _id; }
    set
    {
        if (Equals(_id, value)) return;
        ...
    }
}

private Object _obj;
public Object TheObject
{
    get { return _obj; }
    set
    {
        if (Equals(_obj, value)) return;
        ...
    }
}

Object.Equals(a,b) is null safe. Object.Equals(a,b)是null安全的。 It can answer eg Equals(null, null) which is true. 它可以回答例如Equals(null,null),这是真的。 Apart from that, it just calls the regular Equals() method. 除此之外,它只调用常规的Equals()方法。 As far as I know the clr string and primitive types have equality operators defined that work exactly like Object.Equals(a,b). 据我所知,clr字符串和基本类型具有定义的相等运算符,其工作方式与Object.Equals(a,b)完全相同。

For non-null objA and objB, Object.Equals(objA, objB), objA.Equals(objB) and objB.Equals(objA) should be equivalent if the Equals method is correctly implemented. 对于非null objA和objB,如果正确实现了Equals方法,则Object.Equals(objA,objB),objA.Equals(objB)和objB.Equals(objA)应该是等效的。

The use of Equals(_obj, value) seems correct in the code you posted. 在您发布的代码中,使用Equals(_obj,value)似乎是正确的。

If you want the complete list of equality comparisons, don't forget about objA.ReferenceEquals(objB) which is a kind of equality that is useful in many scenarios. 如果你想要完整的相等比较列表,不要忘记objA.ReferenceEquals(objB),它是一种在许多场景中都很有用的相等。

For any floating point number Equals and == behave differently. 对于任何浮点数, Equals==表现不同。

  • NaN==NaN => false following IEEE logic 遵循IEEE逻辑, NaN==NaN => false
  • NaN.Equals(NaN) => true Follwing the requirement that anything must be equal to itself. NaN.Equals(NaN) => true满足任何事物必须与自身相等的要求。

And of course Equals is overridden ie it works even when the static type is a base type, whereas == is overloaded and only works if the static type has been overloaded. 当然, Equals被覆盖,即使静态类型是基类型也可以工作,而==是重载的,只有在静态类型被重载时才有效。

I almost never call x.Equals(y) directly. 我几乎从不直接调用x.Equals(y) For one it doesn't handle a x being null , and it's asymmetry is ugly IMO. 对于一个它不处理xnull ,它的不对称是丑陋的IMO。 The static object.Equals(x,y) calls the virtual object.Equals(y) method, but adds null handling. 静态object.Equals(x,y)调用虚拟object.Equals(y)方法,但添加了null处理。

IEquatable<T>.Equals(other) is equivalent to object.Equals(other) on all well behaved types, but it avoids boxing in value types. IEquatable<T>.Equals(other)等效于object.Equals(other)上的所有表现良好的类型,但它在值类型避免拳击。

In conclusion I usually prefer == when the static type is known, and EqualityComparer<T>.Default with generic types or if the static type doesn't match the runtime type. 总之,我通常更喜欢静态类型时的== ,以及具有泛型类型的EqualityComparer<T>.Default ,或者静态类型与运行时类型不匹配。


In your example Name and Id behave the same way with == and Equals , since string and int are sealed. 在您的示例中, NameId==Equals行为方式相同,因为stringint是密封的。

TheObject on the other hand exhibits different behavior with == and Equals for certain types. TheObject另一方面表现出不同的行为与==Equals对某些类型。 For example if you use string then Equals will use value equality, and == will use reference equality. 例如,如果使用stringEquals将使用值相等,而==将使用引用相等性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 InternalEquals的实现在哪里(object objA,object objB) - Where is the implementation of InternalEquals(object objA, object objB) IEquatable 和只是覆盖 Object.Equals() 有什么区别? - What's the difference between IEquatable and just overriding Object.Equals()? 什么是Object.Equals(obj,null)和obj == null之间的区别 - Whats the Difference between Object.Equals(obj, null) and obj == null ClassB继承ClassA。 如何检查ClassA objA是否为ClassB类型,然后将objA转换为ClassB? - ClassB inherits ClassA. How do I check if ClassA objA is of ClassB type and then convert objA to ClassB? c#中Object.Equals(object,object)和Object.ReferenceEquals(object,object)之间的区别 - difference between Object.Equals(object,object) and Object.ReferenceEquals(object,object) in c# Object.Equals返回false - Object.Equals return false obj1.Equals(obj2)和c#中的静态Object.Equals(obj1,obj2)有什么区别? - What's the difference between obj1.Equals(obj2) and static Object.Equals(obj1, obj2) in c#? Object.Equals的奇怪实现 - Strange implementation of Object.Equals C#operator ==,StringBuilder.Equals,Object.Equals和Object.ReferenceEquals之间的差异 - C# Differences between operator ==, StringBuilder.Equals, Object.Equals and Object.ReferenceEquals Object.Equals(Object,Object)中的NullReferenceException - NullReferenceException at Object.Equals(Object, Object)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM