-
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
Field-backed properties: language version diagnostics #9038
base: main
Are you sure you want to change the base?
Conversation
proposals/field-keyword.md
Outdated
|
||
If a variable named `field` is declared in a property accessor, an error is reported. | ||
|
||
If an expression `field` would bind to a symbol with language version 13 or earlier, a warning may be reported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why "may" here? Can we make it "will" and better describe the situation if necessary.
Would it be more clear to say something like
If an expression `field` would bind to a symbol with language version 13 or earlier, a warning may be reported. | |
If a symbol named `field` is accessible in the body of a setter or getter that uses the `field` keyword, a warning will be reported. "Accessible" here means that a symbol is available that would be used for binding, if it did not conflict with the `field` keyword. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Changed to "is" rather than "may be".
In terms of accessibility, we should state that it's accessible at the reference to field
. For instance, the following is valid, even though the field
local is accessible at other locations in the accessor body.
object Property
{
get
{
if (field == null)
{
int @field = 0;
return @field;
}
return field;
}
}
proposals/field-keyword.md
Outdated
|
||
If a variable named `field` is declared in a property accessor, an error is reported. | ||
|
||
If an expression `field` would bind to an existing symbol with language version 13 or earlier, a warning is reported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we clarify that this must be a primary expression? Essentially, field
will warn but this.field
willl not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My hesitation with "warnings after upgrade" instead of "warnings before upgrade" is the small chance of this scenario:
-
There's something called
field
in scope. Let's say a protected field in a base class you're implementing from a library that you can't edit. -
You write a new property using
field
as a keyword. This code is good code. -
The brand-new, correct code gets hit with a warning that
field
would have bound to the inherited field namedfield
in C# 13, despite this new property never having compiled with C# 13.
There are variations on this scenario as well. Switching to langversion 14, and bulk applying "use field
," could land you with this same warning despite the new occurrences of field
being correct, and never having existed under C# 13.
So what does a user do?
-
Rename the class field, but this might be a bitter pill if
field
was a genuinely good name for the class field. This might be impossible too, if inheriting from a third-party class. -
Or, put a
#pragma warning disable
on each prop. That's a lot of noise especially for a view model class. -
Or, put a
#pragma warning disable
once at the top of the file because of how noisy the warning is: it's basically all false positives. This is weird, because now in the one place where confusion is likely (where there's a class field calledfield
), the user has disabled the warning.- Or, disable the warning project-wide.
-
Or, quit using the
field
keyword feature in scope of the class field.
In short: Anytime this warning matters (in scenarios where there's something in scope called field
), I expect the occurrences of our breaking changes warning to be absolutely dominated by false positives, and for it to be tuned out one way or another. At the same time I agree we need something.
Regardless of the above, making it an error to declare something called field
inside a property accessor seems like a solid move.
Does this apply to lambda parameters and local function parameters named field
, or only locals?
The cases that would require a permanent warning are essentially when you both:
Our belief is the intersection of these two items will be low. It also falls in line with our stance that this is a breaking change and potentially requires changes to adopt. Yes there are a few cases that can be outlined where you cannot rename the member but those feel sufficiently small. The vast majority of use cases we've seen don't have this intersection of problems. Warnings on upgrade is a problematic area that carry a lot of risk for the product. In this case we feel like the scenarios where customers would be required to use a permanent |
The error applies to parameters named |
Co-authored-by: Rikki Gibson <[email protected]>
Document the breaking change diagnostics that may be reported when re-compiling with the language version that includes field-backed properties.