C# 属性模式匹配成功却报CS0165未赋值局部变量错误原因问询
问题原因解答
这个差异本质是C#编译器明确赋值规则对不同场景下模式变量的赋值状态判定逻辑不同,具体分三种场景说明:
1. if 分支中可以正常运行的原因
模式变量的赋值状态是和is表达式的返回值绑定的:只有is表达式返回true时,对应的模式变量才会被成功赋值。
你将is表达式作为if的判断条件时,只有匹配成功才会进入if代码块,编译器可以100%确定进入块内时message已经完成赋值,因此不会触发CS0165错误。
示例代码:
if (new { Message = "Hello!"} is { Message: string message }) { // 仅匹配成功才会执行到此处,message必然已赋值 Console.WriteLine(message); }
2. 字符串Length匹配可以直接用变量的原因
对于"Hello!" is { Length: int len }这段代码,编译器可以明确推导该匹配永远会成功:
string类型必然存在int类型的Length属性- 输入的
"Hello!"是常量非空字符串,不存在null导致匹配失败的可能
因此编译器会判定len在is表达式执行完成后已经明确赋值,可以直接使用。
3. 匿名类型属性模式触发CS0165的原因
虽然从开发者视角看,你定义的匿名类型确实有string类型的Message属性,匹配必然成功,但C#的明确赋值分析逻辑不会针对匿名类型的属性模式做必然匹配的推导:
- 匿名类型是编译器动态生成的引用类型,明确赋值规则不会跟踪临时匿名实例的非空状态、属性类型的匹配确定性
- 编译器无法保证该
is表达式一定会返回true,因此会认为message可能存在未赋值的情况,直接使用就会触发CS0165错误。
示例报错代码:
var result = new { Message = "Hello!" } is { Message: string message }; // 编译器无法确定message是否已赋值,报CS0165 Console.WriteLine(message);
内容的提问来源于stack exchange,提问作者Amal K
相关产品推荐
相关产品推荐

