Change a dynamic's type in a ternary conditional statement

与世无争的帅哥 提交于 2020-06-23 13:39:10

问题


In C#, the type dynamic allows you to change a variable's type at runtime, for example:

dynamic x = "foo";
x = 42;

Another example:

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

However, when using the shorthand "?:" ternary conditional statement,

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

will not compile:

error CS0173: Type of conditional expression cannot be determined because there is no implicit conversion between 'string' and 'int'

Why is that so?


回答1:


The specification has this to say about how it uses the operands to determine the type of a ternary expression:

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,

o If X and Y are the same type, then this is the type of the conditional expression.

o Otherwise, if an implicit conversion (§11.2) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.

o Otherwise, if an implicit enumeration conversion (§11.2.4) exists from X to Y, then Y is the type of the conditional expression.

o Otherwise, if an implicit enumeration conversion (§11.2.4) exists from Y to X, then X is the type of the conditional expression.

o Otherwise, if an implicit conversion (§11.2) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.

o Otherwise, no expression type can be determined, and a compile-time error occurs.

Obviously none of these (excluding the final statement) are true for string and int, so you get the compile time error.

Essentially, the type of the variable you're assigning the result of your ternary to doesn't have an impact on the resulting type of the ternary expression. If you want to return dynamic, you'll need to cast one of the operands to dynamic directly, like so:

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



回答2:


The type of the conditional operator is determined regardless of the surrounding expression. In other words it really doesn't matter what is before =, (true) ? "foo" : 42; is illegal.

The solution is to cast the types of the operands instead:

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

You can cast just one of them if you wish.


One other thing, the operator's name is "the conditional operator", not "ternary operator", even if it is the only ternary operator in C#.



来源:https://stackoverflow.com/questions/57633328/change-a-dynamics-type-in-a-ternary-conditional-statement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!