c# - 为什么没有 Nullable<T>.Equals(T value) 方法?

标签 c# .net nullable

<分区>

让我们从一段非常简单的代码开始:

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?:

decimal? d = 2;

这次结果将是真、真、假、真。这种情况的解释很容易。 Equals 方法对于 Nullable 类型实现如下:

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

如果 this 有一个值并且 other 参数不为空,则 Decimal.Equals(object value) 将被调用。 Decimal.Equals(object value) 方法以这种方式工作,如果 value 参数不是 decimal 那么结果将始终是 错误的

在我看来,当前的实现并不直观,我想知道为什么 Nullable 不为开发人员提供 Equals 方法的通用版本,例如:

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

    return this.value.Equals(other);
}

是故意为之还是疏忽?

评论 1:

要清楚的简短评论。我建议 Nullable 应该有两个 Equals 方法,即:public override bool Equals(object other)public bool Equals (其他)

最佳答案

而不是写(decimal)2你可以写2m (将在下面使用它)。

当您使用 ==运营商,没有拳击发生。 C# 编译器将选择 operator == 的预定义重载(即 C# 语言规范中定义的重载;这不一定是真正的 .NET 方法)。哪个匹配最好。

有重载:

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

没有像 operator ==(decimal x, int y); 这样的“混合”重载.因为存在来自 int 的隐式转换至 decimal ,你的文字 2转换为 2m当你使用 == 时隐式地.

Equals ,在某些情况下会发生装箱。为此,您不需要可空值。举例来说,所有这些调用:

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);

返回false ! “二”型 Int32不等于 Decimal 类型的“二” .

仅当方法重载导致 int 之间的转换时和 decimal结果会是true吗? .例如:

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

所以虽然 Equals 的额外重载可以添加到Nullable<> ,您描述的行为与 Nullable<> 并不真正相关.

关于c# - 为什么没有 Nullable<T>.Equals(T value) 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18735404/

相关文章:

c# - C#如何获取Windows上运行的程序的名称

c# - 回发后清除隐藏的输入字段

generics - 可空运算符在泛型类中有效吗?

VB.NET 2015 可空整数不使用 If() 运算符?

c# - VB.Net VBDateTimePicker (可空日期时间选择器)

c# - 使用 XElement.Load 时如何添加(或忽略)XML 命名空间

c# - 如何从azure AD应用程序客户端ID生成 token ?

c# - 如何在C#中查找char数组中的字符索引

c# - Reactive Extensions : Split input, 进程,并连接回来

c# - 找到与请求 (GET) 匹配的多个操作