是的,写o is null是有效的,但这不等于o == null强>。
代码
static bool TestEquality(object value) => value == null;
编译成以下 IL 指令。
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: ceq
IL_0004: ret
模式匹配用例编译如下:
static bool TestPatternMatching(object value) => value is null;
IL_0000: ldnull
IL_0001: ldarg.0
IL_0002: call bool [System.Runtime]System.Object::Equals(object, object)
IL_0007: ret
所以,模式匹配 o is null 等价于
Object.Equals(value, null);
因此,在大多数情况下,o 为 null 和 o == null 的行为方式相同。除了相等变体要快一点。 但是!如果我们将 object 替换为以下类,事情将会发生巨大变化。
class TestObject
{
public static bool operator ==(TestObject lhs, TestObject rhs) => false;
public static bool operator !=(TestObject lhs, TestObject rhs) => false;
}
和方法
static bool TestEquality(TestObject value) => value == null;
static bool TestPatternMatching(TestObject value) => value is null;
模式匹配将保持不变,但相等变体将使用以下 IL
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: call bool PatternMatchingTest.TestObject::op_Equality(class PatternMatchingTest.TestObject, class PatternMatchingTest.TestObject)
IL_0007: ret
在这里我们可以看到,== 运算符按预期使用 TestObject 的重载。但是 o is null 和 o==null 会给出不同的结果。所以要小心使用模式匹配 is 操作符。