C#:代码部分:
class ConstValues
{
public const int NULL=1;
}
class Example
{
private enum FormatFunction
{
Date,
Unknown
}
...
FormatFunction returnValue = fn();
...
现在我有两个场景。
当我使用这种方式将返回代码与值进行比较时
if (!returnValue.Equals(ConstValues.NULL))
{
...
我没有得到编译时错误(代码也没有按预期工作,因为这是我错过的一个bug)。
但当我换成时
if (returnValue != ConstValues.NULL)
{
...
我得到了一个编译时的错误,并发现了我犯的错误。
我知道枚举的底层结构是int,但我宁愿在使用Equals时也会出现编译时错误。
为什么第一条路通过,第二条路不通过?
这是因为默认的虚拟Equals方法接收的是对象,而不是像第二个示例中那样的强类型值。它被装箱到对象中,并且将仅在运行时检查类型。
为什么这么做?这个推理非常有趣——如果猫和狗四肢着地行走,就有可能进行比较。通过一些几乎相同的特性来比较两个完全不同的对象。
问题是,当您可以使用强类型对象时。这将防止在编译时发生不好的事情。
!=
是一种语言约定,因此它是特定于C#的。调用此运算符是早期绑定,换句话说,它将在编译时发生。
Equals
是一个框架约定,在本例中是.NET,它在运行时绑定。
当您调用!=
时,决策是由C#编译器在编译过程中做出的,因此您会得到一个错误。当您调用Equals
时,框架会在运行时做出决定。由于您的枚举不是对象类型,它将被转换为对象(装箱),然后运行时将检查您的类型是否覆盖了Equals
方法,因为您没有,它将使用默认实现。
参考型的Equals
如果实例是引用类型,则Equals
的默认实现会检查一个对象引用是否与另一个对象参考相同。如果它们是相同的引用,则返回true。否则返回false。
值型的Equals
如果实例是一个值类型,那么它将测试值是否相等。这就是你的情况。它将检查您拥有的枚举值是否等于常数值。不会显示或抛出任何错误:它等于或不等于。