为什么没有可空< T> .Equals(T值)的方法?

问题描述:

让我们先从一个非常简单的一段代码:

Let's start with a very simple piece of code:

decimal d = 2;

Console.WriteLine("d == 2 = {0}", d == 2);
Console.WriteLine("d == (decimal)2 = {0}", d == (decimal)2);
Console.WriteLine("d.Equals(2) = {0}", d.Equals(2));
Console.WriteLine("d.Equals((decimal)2) = {0}", d.Equals((decimal)2));



结果是4xtrue。现在,让我们改变一个类型的变量的 D 的到的的小数的:

decimal? d = 2;

这一次的结果将是的真,真,假,真的。这种情况的解释是很容易的。 等于的方法,实施了的可空&LT如下:T&GT; 的类型:

This time the result will be True, True, False, True. The explanation of this situation is quite easy. Equals method is implemented as follows for Nullable<T> type:

public override bool Equals(object other)
{
    if (!this.HasValue)
    {
        return (other == null);
    }
    if (other == null)
    {
        return false;
    }
    return this.value.Equals(other);
}

如果的这个的有数值的其他的参数不为空,然后的 Decimal.Equals(对象的值)的将被调用。的 Decimal.Equals(对象的值)的方法的工作以这种方式,如果的的参数没有的小数的那么结果将是永远的 。假

If this has a value and other parameter is not null then Decimal.Equals(object value) will be called. Decimal.Equals(object value) method works in this way, that if value parameter is not decimal then the result will be always false.

在我看来,目前的实现并不直观,我不知道为什么的可空&LT; T&GT; 的不为开发人员提供的的等于的方法如通用版:

It seems to me that the current implementation is not intuitive and I wonder why Nullable<T> doesn't provide developers with generic version of Equals method e.g.:

public bool Equals(T other)
{
    if (!this.HasValue)
        return false;

    return this.value.Equals(other);
}



是不是故意的还是一个疏漏?

Was it done on purpose or is it an omission?

注释1:

一个简短的评论予以明确。我建议的可空&LT; T&GT; 的应该有两个的等于的方法,即:公共覆盖布尔等于(对象等)的和的公共布尔等于(T等)

A brief comment to be clear. I suggested that Nullable<T> should have two Equals methods i.e.: public override bool Equals(object other) and public bool Equals(T other)

而不是写的(十进制)2 你可以写2米(将使用在以下)。

Instead of writing (decimal)2 you can write 2m (will use that in the following).

当您使用 == 运营商,不会发生拳。 C#编译器会选择预定义的过载(即在C#语言规范中定义的过载,这并不一定是真正的.NET方法)运算符== 它匹配。最好

When you use the == operator, no boxing occurs. The C# compiler will choose the pre-defined overload (i.e. the overload defined in the C# Language Specification; this is not necessarily a real .NET method) of operator == which matches best.

有重载:

operator ==(int x, int y);
operator ==(decimal x, decimal y);

有没有混过载像 ==操作符(十进制X, int y)对; 。因为一个隐式转换从 INT 存在小数,您的文字 2 转换为2米隐时使用 ==

There are no "mixed" overloads like operator ==(decimal x, int y);. Because an implicit conversion exists from int to decimal, your literal 2 is converted to 2m implicitly when you use ==.

使用等于,在某些情况下的拳击发生。你并不需要为nullables。为了举例说明,所有这些调用的:

With Equals, in some situations boxing occurs. You don't need nullables for that. To give examples, all of these calls:

object.Equals(2, 2m);
object.Equals(2m, 2);
((object)2).Equals(2m);
((object)2m).Equals(2);
(2).Equals((object)2m);
(2m).Equals((object)2);
(2).Equals(2m);



收益! 二类的Int32 的不等于两化类型的小数

return false! "Two" of type Int32 is not equal to "two" of type Decimal.

只有当方法重载导致转换 INT 小数将结果是真正。例如:

Only when method overloading leads to a conversion between int and decimal will the result be true. For example:

(2m).Equals(2);  // true



因此,虽然额外的超负荷等于可能的加入可空&LT;&GT; ,您所描述是不是真的与可空&LT的行为;&GT;

So while an extra overload of Equals could be added to Nullable<>, the behavior you describe is not really related to Nullable<>.