C#如何使用is运算符拆包Nullable可空类型无需重复写类型名
可空类型
is运算符无类型名拆包方案 你期望的无冗余类型名的拆包写法,在不同C#版本下有对应实现:
C# 11 及以上版本(原生支持)
C# 11 正式增强了模式匹配能力,原生支持你期望的is not null 变量名写法,编译器会自动根据原可空对象的类型推断拆包后变量的类型,无需手动书写类型名,对可空值类型(Nullable<T>)、可空引用类型均生效:
// 你期望的写法可直接编译通过 if(nullable is not null notNullValue) notNullValue.ToString();
对应你给出的LINQ场景,可直接简化为:
class Sample { public Enum? Get() {...} } data.Select(x => (Sample)x) // 无需重复书写Enum类型名 .Where(x => x.Get() is not null enumValue ? StrictCheck(enumValue) : false) .Select(...) .ToArray();
这种写法下,声明的notNullValue/enumValue是拆包后的非空类型,没有任何额外性能开销。
C# 8 ~ C# 10 版本(兼容写法)
低版本没有原生支持该语法,可以用var模式配合空判断实现等效效果,编译器的可空流分析会自动识别判断通过后的变量非空状态,不会产生空引用警告:
// 无需指定具体类型 if (nullable is var notNullValue && notNullValue != null) notNullValue.ToString();
对应LINQ场景改写为:
data.Select(x => (Sample)x) .Where(x => x.Get() is var enumValue && enumValue != null ? StrictCheck(enumValue) : false) .Select(...) .ToArray();
注意:该写法下变量的静态类型仍为原可空类型(比如上例中的
Enum?),但编译器的静态流分析会保证判断分支内变量不可能为null,使用体验和显式指定类型的模式匹配完全一致,不会引入额外性能开销。
C# 8 以下版本(辅助方法方案)
如果需要兼容更老的C#版本,可以通过通用泛型辅助方法实现类似效果:
// 可空值类型扩展 public static bool TryGetValue<T>(this T? nullable, out T value) where T : struct { value = nullable.GetValueOrDefault(); return nullable.HasValue; } // 可空引用类型扩展 public static bool TryGetValue<T>(this T? nullable, out T value) where T : class { value = nullable!; return nullable != null; }
使用方式:
if (nullable.TryGetValue(out var notNullValue)) notNullValue.ToString();
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

