【问题标题】:Change a dynamic's type in a ternary conditional statement在三元条件语句中更改动态的类型
【发布时间】:2019-08-23 21:43:05
【问题描述】:

在 C# 中,dynamic 类型允许您在运行时更改变量的类型,例如:

dynamic x = "foo";
x = 42;

另一个例子:

dynamic x;
if (true)
    x = "foo";
else
    x = 42;

但是,当使用简写“?:”三元条件语句时,

dynamic x = (true) ? "foo" : 42;

不会编译:

错误 CS0173:无法确定条件表达式的类型,因为 'string' 和 'int' 之间没有隐式转换

为什么会这样?

【问题讨论】:

    标签: c# if-statement


    【解决方案1】:

    规范中有这样说它如何使用操作数来确定三元表达式的类型:

    ?: 运算符的第二个和第三个操作数 x 和 y 控制条件表达式的类型。

    •如果 x 的类型为 X 而 y 的类型为 Y,那么,

    o 如果 X 和 Y 是同一类型,那么这是条件表达式的类型。

    o 否则,如果存在从 X 到 Y,但不存在从 Y 到 X 的隐式转换(第 11.2 节),则 Y 是条件表达式的类型。

    o 否则,如果存在从 X 到 Y 的隐式枚举转换(第 11.2.4 节),则 Y 是条件表达式的类型。

    o 否则,如果存在从 Y 到 X 的隐式枚举转换(第 11.2.4 节),则 X 是条件表达式的类型。

    o 否则,如果存在从 Y 到 X 而不是从 X 到 Y 的隐式转换(第 11.2 节),则 X 是条件表达式的类型。

    o 否则,无法确定表达式类型,并出现编译时错误。

    显然,对于stringint,这些(不包括最后的语句)都不正确,因此会出现编译时错误。

    本质上,您将三元表达式的结果分配给的变量类型不会影响三元表达式的结果类型。如果要返回动态,则需要将其中一个操作数直接转换为动态,如下所示:

    dynamic x = (true) ? (dynamic) "foo" : 42;
    

    【讨论】:

      【解决方案2】:

      条件运算符的类型取决于周围的表达式。换句话说,= 之前的内容并不重要,(true) ? "foo" : 42; 是非法的。

      解决方案是转换操作数的类型:

      dynamic x = (true) ? (dynamic) "foo" : (dynamic)  42;
      

      如果你愿意,你可以只施放其中一个。


      另外一点,运算符的名字是“条件运算符”,而不是“三元运算符”,即使它是 C# 中唯一的三元运算符。

      【讨论】:

      • 在执行T? maybe = cond ? new T() : null; 时可以观察到相同的情况。仅当您将最后两个操作数之一转换为 T? 时,它才会进行类型检查。
      猜你喜欢
      • 2014-11-06
      • 1970-01-01
      • 2016-07-17
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 2010-09-13
      • 1970-01-01
      • 2015-04-22
      相关资源
      最近更新 更多