枚举中等号运算符和is运算符之间的差异



给定以下enum

enum ExampleOptions
{
OptionA,
OptionB
}

这两种说法之间有什么真正的区别吗?

ExampleOptions option = ExampleOptions.OptionA;
bool equals1 = option == ExampleOptions.OptionA; // true
bool equals2 = option is ExampleOptions.OptionA; // true

据我所见,使用==is之间的唯一区别主要是is需要一个常量操作数(因此,操作顺序很重要(。

我曾经使用==运算符,只是因为我想避免诸如
!(option is ExampleOptions.OptionA)之类的丑陋语句
但是,在C#9发布并添加了is not运算符之后;我发现is/is not是编写此类语句的一种更干净、更详细的方法。

决定使用哪个运算符是否有任何隐藏的后果?

对于枚举比较,is似乎是语法糖。

bool equals1 = option == ExampleOptions.OptionA; // true
bool equals2 = option is ExampleOptions.OptionA; // true

这两个语句编译到完全相同的IL(在.NET5中测试(,它们调用CIL指令ceq,我认为它代表相等性比较
因此,您认为没有功能差异的假设似乎是正确的。

// [115 13 - 115 61] 
IL_0003: ldloc.0      // option
IL_0004: ldc.i4.0
IL_0005: ceq
IL_0007: stloc.1      // equals1
// [116 13 - 116 61]
IL_0008: ldloc.0      // option
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.2      // equals2

据我所见,使用==和is之间的唯一区别主要是is需要一个常量操作数(因此,操作顺序很重要(。

还有很多不同之处,例如is允许您编写以下语句

val is ExampleOptions.OptionA or ExampleOptions.OptionB or ExampleOptions.OptionD

而不是使用||和重复命名变量的老式语句。

is也不调用operator ==,而是直接检查实例。这不适用于枚举,但如果您有一个带有用户定义的==运算符的对象,而该对象不检查null,则var != null很可能会出现异常而崩溃,而var is not null则会按照您的预期进行操作。

最新更新