C#使用可空类型时如何基于类型执行switch模式匹配?
核心原因
你遇到的问题是.NET的装箱机制导致的,和switch模式匹配本身无关:Nullable<T>类型的null值装箱为object时,CLR会直接返回null引用,不会保留任何Nullable<T>的类型信息,因此你无法从一个值为null的object变量反推它原本属于哪个可空值类型,不管是GetType()调用还是类型模式匹配都做不到。
解决方案
方案一:泛型重载(最优,无性能损耗)
如果可以调整方法签名、不需要强制使用object?作为唯一入参,直接用泛型重载在编译期锁定类型,不会丢失可空类型信息:
// 处理可空布尔 public static string GetSomething(bool? value) => CreateSomething("Integer", value.HasValue ? (value.Value ? 1 : 0) : null); // 处理可空整数 public static string GetSomething(int? value) => CreateSomething("String", value?.ToString()); // 处理字符串 public static string GetSomething(string value) => CreateSomething("String", value); // 其他需要支持的类型可继续扩展重载
调用时会自动匹配对应重载,即便是传入(bool?)null也会正确走到布尔分支,传入Integer作为第一个参数。
方案二:保留object入参的兼容方案
如果必须保留object?的入参签名,需要同时传入预期的类型信息才能正确判断:
public static string GetSomething(Type expectedType, object? value) => expectedType switch { Type t when t == typeof(bool?) || t == typeof(bool) => CreateSomething("Integer", value is bool b ? (b ? 1 : 0) : null), Type t when t == typeof(int?) || t == typeof(int) => CreateSomething("String", value is int i ? i.ToString() : null), Type t when t == typeof(string) => CreateSomething("String", value), _ => throw new ArgumentOutOfRangeException(nameof(expectedType)) }; // 调用示例 GetSomething(typeof(bool?), null); // 正确匹配布尔分支 GetSomething(typeof(bool), false); GetSomething(typeof(string), "test");
补充说明
你写的理想示例代码无法运行的原因是:bool?类型的模式匹配对于object类型的入参来说,只会匹配非null的bool类型值,null的object不会命中任何值类型的模式分支,因此永远无法处理可空布尔的null场景。
内容的提问来源于stack exchange,提问作者rklec
相关产品推荐
相关产品推荐

