让我们从一段非常简单的代码开始:
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;
这次的结果将是 True, True, False, True。这种情况的解释非常简单。Equals 方法是针对 Nullable<T> 类型实现的,实现方式如下:
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)方法。该方法的工作方式是,如果value参数不是decimal类型,则结果将始终为false。
我认为当前的实现方法不够直观,我想知道为什么Nullable<T>没有提供带泛型的equals方法,比如:
public bool Equals(T other)
{
if (!this.HasValue)
return false;
return this.value.Equals(other);
}
这是故意的还是疏忽了呢?
评论1:
简要说明一下。我建议 Nullable<T> 应该有两个 Equals 方法,即:public override bool Equals(object other) 和 public bool Equals(T other)
T
不一定是IEquatable<T>
。 - Mike Zboraypublic bool Equals(T? other)
方法吗?否则,对于声明decimal? d1, d2;
,d1.Equals(d2)
将是无效的。 - user743382Equal(object)
重载。但是除非你也在T
上有一个,否则通用的Equals没有意义。 - Mike ZborayT
可以隐式转换为T?
,因此仍然可以在没有特定重载的情况下调用T
。而且如果没有T?
的重载,使用int?
参数调用decimal?.Equals
仍将存在与本问题相同的问题,因为它将解析为decimal?.Equals(object)
,而不会将包含的int
值转换为decimal
类型。 - user743382