为什么条件运算符在用于字符串插值时会关心类型?

Why does the conditional operator care about types when used in string interpolation?

我们中的很多人都非常熟悉 CS0173 编译器错误的意外事件,这是一种类型转换错误:

Type of conditional expression cannot be determined because there is no implicit conversion between 'class1' and 'class2'

今天,我做了一个假设,我可以在字符串插值中使用条件运算符 ?:,它不会关心用于结果或替代的类型。在我的例子中,我想检查 long 以确定它的值是否小于零,如果是,则显示 string 表示 Not Available,如果不是,则简单显示long的值:

long x = 5;
string example = $"{(x < 0 ? "Not Available" : x)}";

这导致编译器错误 CS0173,因为结果是 string 类型,而替代类型是 long。这是一个简单的修复,使用 .ToString():

long x = 5;
string example = $"{(x < 0 ? "Not Available" : x.ToString())}";

但现在我很好奇...


为什么条件运算符 ?: 在字符串插值内部使用时甚至会关心类型,因为无论如何都要显示字符串表示形式?

操作员不知道他们正在使用的上下文。在 x+1y=x+1 两种情况下,+ 运算符只知道它接受两个参数并 return 计算结果。为了说明,就像

T Sum<T>(T numA, T numB){
//Do stuff
}

?:也是如此,它是一个接受三个参数和return结果的方法。结果是强类型的,从输入中推断出来。只有这样结果才会被传递给插值,这在你的情况下永远不会发生,因为三元运算符会给出编译时错误,因为它不能隐式转换 longstring.

编辑: 正如@RandRandom 在评论中指出的那样,现在 C# 9 可以做到这一点,因为它们 changed the implementation of the ternary operator.

您假设三元条件运算符 ?: 在字符串插值内部使用时关心类型是错误的。因为它甚至不需要在字符串插值内。 c# 是一种强类型语言(每个变量的类型都是已知的,有 dynamic 关键字,但那是另一回事)。

例如,您甚至不能执行以下操作,因为类型未知(是长还是字符串?)

long x = 5;
var example = x < 0 ? "Not Available" : x;