Ternary operator doesn't work with delegate natural type (and no way to force it) #8893
Unanswered
BlinD-HuNTeR
asked this question in
Language Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Related to #73347 and #8869.
C# 10 has introduced Delegate Natural Types, which means that lambdas and method groups can now be assigned to an implicitly-typed variable, or even used directly as an expression, if target-typed to
Delegate
orobject
:However it was made in a way such that Lambdas and Method Groups are still not treated as first-class objects: instead the natural type inference works only in the above scenarios. For anything else, a method group is still treated like pre-C#10 (you can do nothing with it, other than invoke it).
I believe it would be really nice if a method group could be used directly as an object, and even use its "members" (the "members" of a method group or lambda are the members of its inferred delegate type, plus members of
Delegate
andobject
:Now it might be a little overkill to suddenly treat all occurrences of a method group as a concrete object, and it might lead to errors with the developer unknowingly instantiating a delegate. If that's the case, then it could be made such that the natural type will only apply when the expression is parenthesized. This would be similar to JavaScript, when you can use parentheses to force an indirect invocation:
However even though the above is valid C#, it doesn't work that way. Putting parentheses around a method group will always be a direct invocation, no matter how many parentheses you use, they will be ignored (you actually have to use 2 or more pairs, using only one, causes a parsing error).
Which finally comes to my point: any attempt to use a method group (or lambda) as an expression, except those specific scenarios, will be treated like pre-C# 10 era. And that's what happens with ternary operator:
Yet it can be easily solved by introducing a method that returns its own parameter:
So my suggestion is basically introduce the ability to treat lambdas and/or method groups as an expression of the inferred delegate type, either all the time, or only when parenthesized. Either way, it would be really nice for some functional programming scenarions, like composition or partial application, as you can now use a method as a regular object with members.
There's a point of attention though: this would be a breaking change for the parenthesized invocation case.
((MyMethods.MyMethod))()
is currently a direct invocation, and with that proposal, it would cause the instantiation of aFunc<int>
(behaviorally, the program is still the same).Although, correct me if I'm wrong, but the C# language design team seems to be more lenient with breaking changes now, than it has been in the past. And also, who tf uses parentheses around an invoked method? It shouldn't even be valid C# in the first place.
Spoiler
As a last resort, in the case that all of this is going to be dismissed, could you, maybe, just fix the ternary operator, such that it calls
BindToNaturalType
, when the inference would fail otherwise?Beta Was this translation helpful? Give feedback.
All reactions