class C<T> where T : struct {
bool M1(object o) => o is T;
bool M2(object o) => o is T?;
}
上面的两种方法在传递 null
时似乎表现相同引用或盒装T
值(value)。但是,生成的 MSIL 代码有点不同:
.method private hidebysig instance bool M1(object o) cil managed {
.maxstack 8
IL_0000: ldarg.1
IL_0001: isinst !T
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
}
对比
.method private hidebysig instance bool M2(object o) cil managed {
.maxstack 8
IL_0000: ldarg.1
IL_0001: isinst valuetype [mscorlib]System.Nullable`1<!T>
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
}
如您所见,o is T?
表达式实际上对 Nullable<T>
执行类型检查类型,尽管可空类型由 CLR 专门处理,因此 C# 表示盒装 T?
值为 null
引用(如果 T?
没有值(value))或盒装 T
值(value)。似乎不可能得到 Nullable<T>
的盒子输入纯 C# 或什至可能输入 C++/CLI(因为运行时处理 box
操作码以支持此“T?
=> T
box/null
”装箱)。
我是不是遗漏了什么或 o is T?
实际上等同于 o is T
在 C# 中?
最佳答案
根据规范(强调我的),在 E is T
中,T
的不可空值类型和相应的可空类型的处理方式相同:
7.10.10 The
is
operatorThe
is
operator is used to dynamically check if the run-time type of an object is compatible with a given type. The result of the operationE is T
, whereE
is an expression andT
is a type, is a boolean value indicating whetherE
can successfully be converted to typeT
by a reference conversion, a boxing conversion, or an unboxing conversion. The operation is evaluated as follows, after type arguments have been substituted for all type parameters:
If
E
is an anonymous function, a compile-time error occursIf
E
is a method group or the null literal, of if the type ofE
is a reference type or a nullable type and the value of E is null, the result is false.Otherwise, let
D
represent the dynamic type ofE
as follows:
- If the type of
E
is a reference type,D
is the run-time type of the instance reference byE
.If the type of
E
is a nullable type,D
is the underlying type of that nullable type.If the type of
E
is a non-nullable value type,D
is the type ofE
.The result of the operation depends on
D
andT
as follows:
- If
T
is a reference type, the result is true ifD
andT
are the same type, ifD
is a reference type and an implicit reference conversion fromD
toT
exists, or ifD
is a value type and a boxing conversion fromD
toT
exists.- If
T
is a nullable type, the result is true ifD
is the underlying type ofT
.- If
T
is a non-nullable value type, the result is true ifD
andT
are the same type.- Otherwise, the result is false.
关于c# - C# 中的 `x is int?` 和 `x is int` 有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42637956/