正如我在回答 this question ,我观察到 switch 表达式特有的一个非常奇怪的行为——当它们有一个不明确的类型时,它们似乎能够推断出它们的类型。
例如,这不会编译
double a = new Random().Next(2) == 0 ? (short)1 : (uint)1;
因为编译器“不看”double a
部分类型检查时,看到表达式是类型 short
或 uint
.表达式不能有两种类型,因此会输出错误。这可以。众所周知,C# 不会查看您分配给的变量类型,就像在泛型中一样:static T F<T>() => default(T);
double d = F(); // can't infer that T is double
然而 , switch 表达式打破了这个“规则”。如果我用 switch 表达式重写第一个代码片段:double a = (new Random().Next(2) == 0) switch {
true => (short)1,
false => (uint)1
};
然后突然编译!与第一个代码片段不同,编译器似乎注意到了 double a
部分并发现我想要一个 double
.我试着看 docs用于 switch 表达式,但它没有提到它将执行任何自动转换为结果类型或类似的东西。为什么 C# 在处理 switch 表达式时如此聪明,而在处理其他类型的表达式(如三元运算符)时却不是?
最佳答案
来自 C# 语言 proposal用于 switch 表达式;
The type of the switch_expression is the best common type of the expressions appearing to the right of the => tokens of the switch_expression_arms if such a type exists and the expression in every arm of the switch expression can be implicitly converted to that type. In addition, we add a new switch expression conversion, which is a predefined implicit conversion from a switch expression to every type T for which there exists an implicit conversion from each arm's expression to T.
最常见的类型?
In some cases, a common type needs to be inferred for a set of expressions. In particular, the element types of implicitly typed arrays and the return types of anonymous functions with block bodies are found in this way.
Intuitively, given a set of expressions
E1...Em
this inference should be equivalent to calling a methodTr M<X>(X x1 ... X xm)
with the Ei as arguments.
More precisely, the inference starts out with an unfixed type variable X. Output type inferences are then made from each Ei to X. Finally, X is fixed and, if successful, the resulting type S is the resulting best common type for the expressions. If no such S exists, the expressions have no best common type
由于这无法编译,因此会出现“没有最佳类型..”错误;
var x = (id == 0) switch
{
true => (short)1,
false => (uint)1
};
你的例子 double x ...
约束输出类型,改变如何推断 switch 表达式的类型。但这只是我的猜测。而conditional operator有非常严格的规定;
The second and third operands, x and y, of the ?: operator control the type of the conditional expression.
- If x has type X and y has type Y then
- If an implicit conversion (Implicit conversions) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
- If an implicit conversion (Implicit conversions) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
- Otherwise, no expression type can be determined, and a compile-time error occurs.
- If only one of x and y has a type, and both x and y, of are implicitly convertible to that type, then that is the type of the conditional expression.
- Otherwise, no expression type can be determined, and a compile-time error occurs.
TLDR;类型推断/提升规则非常不同。
关于c# - 为什么 switch 表达式会从周围的上下文中推断出表达式类型,而其他类型不明确的表达式却不会?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63257017/