如何处理依赖枚举值的可空返回?替代空原谅运算符的方案
问题
我有一个返回元组(MyEnum, Package?)的方法:仅有一种MyEnum枚举值对应Package非空,其余所有枚举值均对应Package为null。示例代码如下:
(MyEnum response, Package? package) MyMethod() { if (Today == NiceDay) { return (MyEnum.Happy, new Package("I'm happy!")); } if (Today == RainyDay) { return (MyEnum.Pensive, null); } if (Today == SnowyDay) { return (MyEnum.Cold, null); } }
当尝试直接访问MyMethod().package.message时,编译器会触发空引用警告。我了解空原谅运算符,但认为这只是临时解决方案。请问能否让编译器根据MyMethod().response是否为MyEnum.Happy,自动识别package是否非空?还是只能使用空原谅运算符处理该场景?
解决方案
当然可以让编译器自动识别package的非空性,不需要依赖空原谅运算符,推荐两种方案:
1. 使用模式匹配(C# 8.0+)
利用C#的模式匹配语法,直接在判断枚举值的同时解构元组,编译器会自动推断此时package非空:
// 方式1:先获取结果再判断 var result = MyMethod(); if (result.response == MyEnum.Happy) { // 编译器确认此处package非空,无警告 Console.WriteLine(result.package.Message); } // 方式2:直接在条件中解构匹配 if (MyMethod() is (MyEnum.Happy, var package)) { Console.WriteLine(package.Message); // 无空引用警告 }
这种方式不需要修改原方法的返回类型,直接通过语法让编译器理解枚举值与对象非空性的关联。
2. 自定义带空校验属性的结构体
如果需要更严谨的类型约束,可以把元组替换为自定义结构体,通过[NotNullWhen]属性明确告诉编译器:当Response为MyEnum.Happy时,Package一定非空。
using System.Diagnostics.CodeAnalysis; public struct MyMethodResult { public MyEnum Response { get; } // 标注:当Response等于MyEnum.Happy时,Package不为null [NotNullWhen(ReturnValue = MyEnum.Happy)] public Package? Package { get; } public MyMethodResult(MyEnum response, Package? package) { Response = response; Package = package; } // 可选:添加解构方法,保持和原元组类似的使用体验 public void Deconstruct(out MyEnum response, out Package? package) { response = Response; package = Package; } } // 修改原方法返回自定义结构体 public MyMethodResult MyMethod() { if (Today == NiceDay) { return new MyMethodResult(MyEnum.Happy, new Package("I'm happy!")); } return Today == RainyDay ? new MyMethodResult(MyEnum.Pensive, null) : new MyMethodResult(MyEnum.Cold, null); }
使用时,只要判断Response为MyEnum.Happy,编译器就会自动识别Package非空:
var result = MyMethod(); if (result.Response == MyEnum.Happy) { Console.WriteLine(result.Package.Message); // 无警告 }
为什么原元组不行?
原生元组的两个元素是独立的类型成员,编译器无法建立“枚举值与对象非空性”的关联关系,因此无法自动推断。而上述两种方案都是通过语法或属性给编译器补充了这层关联信息。
内容的提问来源于stack exchange,提问作者Artur S.
相关产品推荐
相关产品推荐

