关于C# 9 Target-Typed Conditional Expression的方法调用歧义疑问
关于C#9目标类型条件表达式的重载决议疑问解答
先明确你的问题核心:你看到官方文档说引入目标类型条件表达式后,M(b ? 1 : 2, 1)会存在调用歧义,但实际编译后始终调用M(long, long),这里的关键是重载决议的整体匹配优先级,而非单个参数的目标类型推断。
拆解两种场景的编译逻辑:
1. C#9之前的行为
条件表达式b ? 1 : 2的类型是int(两个分支都是int字面量)。此时调用重载时:
- 调用
M(short, short)需要把两个int参数显式转换为short(C#中int转short属于缩小转换,编译器不会自动隐式完成); - 调用
M(long, long)只需要把两个int参数隐式扩大转换为long,这是编译器允许的隐式转换。
因为隐式转换优先级高于显式转换,编译器直接选择M(long, long),没有歧义。
2. C#9引入目标类型条件表达式后的行为
这个特性允许条件表达式的类型由上下文(即目标重载的参数类型)决定,但重载决议是针对整个方法调用的所有参数判断匹配度:
- 候选重载
M(short, short):第一个参数的条件表达式可被目标类型short约束(字面量1、2在short范围内,能隐式转short),但第二个参数1是int,仍需显式转换为short; - 候选重载
M(long, long):两个参数都能通过隐式扩大转换完成类型匹配,无需显式转换。
编译器会比较候选的整体匹配质量,M(long, long)的参数转换优先级更高(全隐式转换),因此仍然被选中,不会出现文档提及的歧义情况。
为什么文档说有歧义?
文档提到的歧义场景,大概率是指两个候选重载所有参数转换优先级一致的情况。比如存在以下重载:
static void M(int i, int ii) => Console.WriteLine("int"); static void M(long i, long ii) => Console.WriteLine("long");
此时调用M(b ? 1 : 2, 1),条件表达式既可以被推断为int(匹配第一个重载),也可以被推断为long(匹配第二个重载),且两个重载的参数转换都是隐式的,这时候才会出现真正的歧义,编译器会报错。
你的示例中因为M(short, short)需要显式转换第二个参数,所以不存在真正的歧义,编译器能明确选出更优的M(long, long)。
内容的提问来源于stack exchange,提问作者Zze
相关产品推荐
相关产品推荐

