C# 8:为何部分Switch表达式返回元组的代码可运行,部分不可?
问题:为什么这段C#元组解构代码无法运行?
先看两段可正常运行的代码:
(Func<Window> win1, int i1) = ( () => new Window(), 1);
(int i2, int i3) = 1 switch { 1 => (2, 1), _ => throw new ArgumentOutOfRangeException() };
但下面这段代码无法编译运行:
(Func<Window> win2, int i4) = 1 switch { 1 => (() => new Window(), 1), _ => throw new ArgumentOutOfRangeException() };
原因分析
核心问题出在C#编译器对switch表达式返回值的类型推断逻辑上:
- 第一段代码是直接给解构变量赋值元组字面量,编译器可以通过左侧的变量类型(
Func<Window>和int)反向推导元组的具体类型,所以能正常识别。 - 第二段代码的switch返回的是值类型元组
(int, int),所有分支返回的类型一致且都是基础值类型,编译器能轻松推断出匹配左侧解构的类型,因此运行正常。 - 第三段代码中,switch分支返回的
(() => new Window(), 1)是匿名元组,编译器无法自动推断这个元组的第一个元素是Func<Window>类型(它只会将其视为无明确类型的匿名方法)。而switch表达式要求所有分支返回的类型必须统一且可被明确推断,这里因为没有显式指定元组的具体类型,编译器无法匹配左侧的(Func<Window>, int)解构目标,最终导致编译失败。
解决方法
给switch分支的元组显式指定类型即可,比如:
(Func<Window> win2, int i4) = 1 switch { 1 => ((Func<Window>)(() => new Window()), 1), _ => throw new ArgumentOutOfRangeException() };
或者:
(Func<Window> win2, int i4) = 1 switch { 1 => new (Func<Window>, int)(() => new Window(), 1), _ => throw new ArgumentOutOfRangeException() };
内容的提问来源于stack exchange,提问作者kumm69
相关产品推荐
相关产品推荐

