c# - C# 中的 `x is int?` 和 `x is int` 有区别吗?

标签 c# types nullable cil boxing

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 operator

The 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 operation E is T, where E is an expression and T is a type, is a boolean value indicating whether E can successfully be converted to type T 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 occurs

  • If E is a method group or the null literal, of if the type of E 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 of E as follows:

    • If the type of E is a reference type, D is the run-time type of the instance reference by E.
    • 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 of E.

  • The result of the operation depends on D and T as follows:

    • If T is a reference type, the result is true if D and T are the same type, if D is a reference type and an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
    • If T is a nullable type, the result is true if D is the underlying type of T.
    • If T is a non-nullable value type, the result is true if D and T are the same type.
    • Otherwise, the result is false.

关于c# - C# 中的 `x is int?` 和 `x is int` 有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42637956/

相关文章:

python - 为什么字符串不变成整数?

matrix - 访问 Julia 矩阵中的任意行

sql - 在grails中,我已经投入生产后,需要将域类中的字段更改为可为空

c# - 为什么 TargetNullValue 更新可为空的 Source

c# - Automapper:处理对象到对象映射的可空属性

c# - 以编程方式更改 WPF 可编辑组合框的背景颜色

c# - yield break有什么用?

c# - 如何解释此堆栈跟踪

c# - LINQ 到数据 : Clever Type Recognition

c# - 没有为此对象定义无参数构造函数 - 无法解决