-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue: conditional operator ?:
cannot resolve implicit conversion to one another
#563
Comments
Here's what the specs say:
In terms of the specs the produced error is in order. But I would like to know the objective reason behind this definition. It somehow feels weired without knowing the background. |
As to the background, I think the general answer is that C# avoids target-typing (outside-in). If everything is inferred inside-out it keeps inference straightforward and unidirectional, which is a benefit both to C# language designers and consumers. |
But even if that reason is true it won't argue against converting the third operand to the second first. Btw, a complex type balancing is done at the null-coalescing operator |
Might be nice if there were some kind of rules regarding precedence/inference of the operands, at least in cases of ambiguity. For example in the cases above I'd kind of expect that if the compiler couldn't determine the type of expressions between two types that are implicitly castable to each other that it might favor the type of the first operand. When it comes to expressions of var value1 = (condition) ? 123 : default;
var value2 = (condition) ? default : 123; What I wouldn't expect is for the target type to play into that inference. For example: double result = (_denominator != null) ? _denominator : 1d; I'd expect the conditional expression to evaluate to type |
I'm going to assume that this is because looking at said expression you might not immediately understand what it's going to do and you might make the wrong assumption. You can make the case that it should immediately cast |
@HaloFour Because we read this language from left-to-right I just find it logical if the second operand's type had precedence over the third's. If operators ( |
It's not intuitive to me that one ternary operand should be preferred over the other. I mean sure, I'd live with it, but it feels like a wart. I like knowing that the order of the two operands is just about readability and not about importance. |
Perhaps ternary expressions could be treated as a union type which is reduced by the target type. So for this example: double result = (_denominator != null) ? _denominator : 1d; the following would be pseudo steps for evaluating the type:
(In this context, the union type is resolved prior to assignment. This does not cover the topic of unresolved union types, i.e. |
That will be 'ValueType'. |
@lachbaer I'm not sure what you mean. A union type represents an "or" between two or more types. |
Isn't it the common base type? Otherwise you get the same ambiguity again, shall the common type be A or B when they both can implicitly converted to one another? |
@lachbaer The ambiguity exists at step 2. But a target type was specified, so the ambiguity is resolved in steps 3-4. There is no need to find a base type because the implicit conversion to Now if we write |
I think I would find it pretty confusing if |
Old issue - i know: I see why people argue for this to be confusing in general assignment scenarios - but what about scenarios where there is no confusion, because the type casting is deterministic if a type is used instead of using var. Is the idea of target typed implicit casting still off the table currently? Personally i always think of ternary expressions as a nice way to write code in a more compact way, if the expression contents are short. Having to write code like this instead of being able to use ternary expression seems unnecessarily verbose. |
I think #877 can resolve this since there is a target-type in all examples (except for |
While trying something I ran into the following phenomenon:
The marked line gets "Error CS0172: Type of conditional expression cannot be determined because 'NNDouble' and 'double' implicitly convert to one another".
Of course this could be helped by explicity converting one of the operands.
But from a naive point of view, shouldn't the compiler try to implicitly convert the second operand to the result type first, making that the target type of the whole expression? Or in case there is no available return type (
var
,dynamic
) try to convert the third operand to the second one first?Examples:
At least we are reading this language left-to-right, and using the second operand to evaluate the whole result type seems logical to me this way.
(Edit: changed "first" and "second" operand to "second" and "third" operand, according to the specifications.)
The text was updated successfully, but these errors were encountered: