-
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
Try to infer member and return types if omitted #2996
Comments
Unlike local variables class members can forward reference other members which can lead to very complicated circular and ambiguous scenarios. The team has expressed multiple times in the past that it's not worth the effort it would require to put into such a feature. Also, when designing local functions the choice was between allowing for return type inference or hoisting, the latter allowing for recursive scenarios. The team choose hoisting. https://blogs.msdn.microsoft.com/ericlippert/2009/01/26/why-no-var-on-fields/ |
I understand the technical challange involved, though I personally feel it would be worth the effort to at least try (I believe the blog post was written before the Roslyn compiler was put to use). I believe the TypeScript compiler is able to successfuly deal with similar level of circularity, so maybe hope shouldn't be lost. I guess this suggestion is intended to investigate a possible approach for syntax if at some future point they decide to to retry and tackle the challange. |
Per the following comment and linked design meeting notes (post-Roslyn) it sounds like the team isn't interested: IMO, technical considerations aside, it's not a good idea. The return type of a member is a part of the public contract of that type. Making it subject to type inference can both make it very difficult to discern what that contract is by reading the source as well as makes it too easy to accidentally change by modifying the body of the member. |
Well, I guess that's mostly a subjective view (as a longtime TypeScript user I found it to be tremendously practical). Anyway, I experimented a little with the TypeScript compiler to see how it handles circularity when inferring method return types: class Test
{
test1()
{
return this.test2();
}
test2()
{
return this.test1();
}
} The error it gives is:
(a similar error is given for To be honest, for years using TypeScript I have never actually encountered this error.. :) But it seems like it was able to deal with the situation pretty well so I won't lose hope that C# might be able to do the same one day (I guess..?). |
Note that TS and C# are very differnet languages. For example, TS types have no actual bearing on runtime behavior. The types can be wrong, or inferred differently, and that won't break the runtime behavior of any existing apps. That's not hte case with C#/.net |
Well, the compiler can always fail to infer the type given it decides it can't figure it out (or it's too expensive or complicated), and require the user to annotate it directly, so the inference is not guaranteed to be consistently available (that's why I titled the issue "Try to infer.."). |
The type of a member is part of its contract in C#, and requiring being explicit about contracts is an intended and desirable design point of C# that we do not intend to change. |
Related to #2227, #1129
Since, if I understand correctly, the
var
keyword has been reserved for implicitly typed variables only, a different keyword might be needed for inferred member, method and local function return types - say, one analogous toauto
in C++. One major downside would be that it would result in having two redundant keywords having practically the same semantics.An alternative approach would be to optionally allow member / return types to be omitted (somewhat analogous to the approach taken by TypeScript). I'll try to explore it in detail here.
Overall, it doesn't seem to conflict with existing syntax, though might require some initial subjective adjustment on the part of the user:
Overloaded methods should not be impacted, since return types are not used for overload resolution:
Static members and operators:
Indexers:
Same applies to struct members, when applicable:
Analogous syntax could apply to local functions as well, though it might visually appear to resemble function invocation (thus might require some getting used to):
The non-shorthand form of a local function might require some lookahead to parse (I'm not currently sure if it'd be possible to do so unambiguously):
The text was updated successfully, but these errors were encountered: