对象之间的区别。= (objA, objB)、Equals(objB)和objA == objB用于CLR类型?

时间:2021-10-03 16:11:20

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. 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.

我确实意识到,在CLR之外,有人可以轻松实现IEqualtable Equals,并以不正确的方式重载==运算符。我不担心人们不恰当地实施这些措施。我关注的是类(包括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的文件。等于(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;
        ...
    }
}

2 个解决方案

#1


6  

Object.Equals(a,b) is null safe. It can answer e.g. Equals(null, null) which is true. Apart from that, it just calls the regular Equals() method. As far as I know the clr string and primitive types have equality operators defined that work exactly like Object.Equals(a,b).

Object.Equals(a,b)是零的安全。它可以回答:等于(null, null)这是真的。除此之外,它只调用常规的Equals()方法。据我所知,clr字符串和基元类型具有定义为与Object.Equals . 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.

对于非空objA和objB,对象。Equals(objA, objB)、objB.Equals(objB)和objB.Equals(objA)应该是等价的,如果Equals方法被正确实现。

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.

如果您想要完整的平等比较列表,请不要忘记object . referenceequals (objB),它是一种在很多情况下都有用的平等。

#2


1  

For any floating point number Equals and == behave differently.

对于任何浮点数=和=的行为都不同。

  • NaN==NaN => false following IEEE logic
  • 按照IEEE逻辑,NaN==NaN =>假
  • NaN.Equals(NaN) => true Follwing the requirement that anything must be equal to itself.
  • NaN. equals (NaN) => true following the requirements that anything must be equal to yourself。

And of course Equals is overridden i.e. 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. For one it doesn't handle a x being null, and it's asymmetry is ugly IMO. The static object.Equals(x,y) calls the virtual object.Equals(y) method, but adds null handling.

我几乎从不直接调用x。= (y)首先它不能处理x为空的情况,它的不对称在我看来很丑陋。静态object.Equals(x,y)调用virtual 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 . 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 。默认使用泛型类型,或者如果静态类型与运行时类型不匹配。


In your example Name and Id behave the same way with == and Equals, since string and int are sealed.

在示例名称和Id中,与=和=的行为相同,因为字符串和int是密封的。

TheObject on the other hand exhibits different behavior with == and Equals for certain types. For example if you use string then Equals will use value equality, and == will use reference equality.

另一方面,对于某些类型,TheObject用==和=显示不同的行为。例如,如果您使用string,那么=将使用值相等,==将使用引用相等。

#1


6  

Object.Equals(a,b) is null safe. It can answer e.g. Equals(null, null) which is true. Apart from that, it just calls the regular Equals() method. As far as I know the clr string and primitive types have equality operators defined that work exactly like Object.Equals(a,b).

Object.Equals(a,b)是零的安全。它可以回答:等于(null, null)这是真的。除此之外,它只调用常规的Equals()方法。据我所知,clr字符串和基元类型具有定义为与Object.Equals . 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.

对于非空objA和objB,对象。Equals(objA, objB)、objB.Equals(objB)和objB.Equals(objA)应该是等价的,如果Equals方法被正确实现。

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.

如果您想要完整的平等比较列表,请不要忘记object . referenceequals (objB),它是一种在很多情况下都有用的平等。

#2


1  

For any floating point number Equals and == behave differently.

对于任何浮点数=和=的行为都不同。

  • NaN==NaN => false following IEEE logic
  • 按照IEEE逻辑,NaN==NaN =>假
  • NaN.Equals(NaN) => true Follwing the requirement that anything must be equal to itself.
  • NaN. equals (NaN) => true following the requirements that anything must be equal to yourself。

And of course Equals is overridden i.e. 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. For one it doesn't handle a x being null, and it's asymmetry is ugly IMO. The static object.Equals(x,y) calls the virtual object.Equals(y) method, but adds null handling.

我几乎从不直接调用x。= (y)首先它不能处理x为空的情况,它的不对称在我看来很丑陋。静态object.Equals(x,y)调用virtual 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 . 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 。默认使用泛型类型,或者如果静态类型与运行时类型不匹配。


In your example Name and Id behave the same way with == and Equals, since string and int are sealed.

在示例名称和Id中,与=和=的行为相同,因为字符串和int是密封的。

TheObject on the other hand exhibits different behavior with == and Equals for certain types. For example if you use string then Equals will use value equality, and == will use reference equality.

另一方面,对于某些类型,TheObject用==和=显示不同的行为。例如,如果您使用string,那么=将使用值相等,==将使用引用相等。