-
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
Proposal: Expose auto property backing field into getter and setter scope #1497
Comments
For the |
As I mentioned in #1336 (comment): Do please consider closing this issue if at least one of the other ones would solve it in order to keep the amount of duplicates low. |
I also don't like duplicate issues, but I think this one significantly differs to the original proposal of #140 (and that's the closest proposal of the list). Well, you could say it is a duplicate to @BobSammers' #140 (comment) and #140 (comment). But those comments are hard to reference. @anders-liu you may add a paragraph which mention #140 and work out the differences. I'm undecided if I prefer the modifierless #140 or #1497. I'm also not sure if I like the I don't like option 1. IMO an attribute should no change the language grammer. |
I think option 2 is the best idea here. Another alternative, if the use of a keyword is really desired, would be a public int Age
{
using { int _age = 0; }
get { return _age; }
set
{
if (value < 0 || value > 300)
throw new System.ArgumentOutOfRangeException();
_age = value;
}
} |
Is there any advantage to public int Age
{
int _age = 0;
get => ...;
set => ...;
}
I can't imagine anyone wants to introduce a keyword for the sake of it, just if it eliminates a breaking change to existing code (and only then if it's considered to be a significant problem). For me, this family of proposals (as it seems to have become) has two goals:
Scoping a field to the property with either a using statement or just a normal field declaration solves the first issue but not the second. Another idiom that is made a little easier by avoiding the need to explicitly declare the backing field is the single-line property, such as this example from one of my comments in #140: public int SomeProperty => field = isDirty ? RecalcProperty() : field; There is nowhere obvious in a line like this to declare a backing field scoped only to the property. For these reasons, in #140 I have advocated an approach that uses public backed int SomeProperty => field = isDirty ? RecalcProperty() : field; I agree with @quinmars that the language shouldn't be altered by the use of attributes, so I wouldn't go along with their use as described in the original post's "alternatives" section. |
Thank you guys for pointing out the similar ones; I actually did a search before writing this proposal but I didn't know which keywords should I use so I didn't see my ideal proposal. (The 'original proposal' is also mine, so there isn't any difference between them; I just posted it in a wrong way.) But yes, the ones you pointed out definitely fit my expectation, I don't care the detailed syntax change, I only want to control over the auto generated backing field of a property. So closed this one; thank you guys! |
#440
The original proposal is here: https://github.com/anders-liu/csharplang/blob/al/property-backing-field/proposals/property-backing-field.md
Property Backing Field
Summary
Expose auto property backing field into getter and setter scope through
field
contextual keyword.Motivation
Consider a property with checking on its value is being set.
For checking the value, we have to define a field on the class, which is 'globally' used between getter and setter, as well as other scopes inside a type definition. As all 'global' things are evil, developper may set invalid value to the
_age
field elsewhere in the class, for example:This could happen when codebase goes large and developers involved go many.
Auto property may help to hide the backing field of a property, but we lose the chance to check value.
So it's necessary to involve a contextual keyword, which stands for the backing field of a property but can only be accessed in the scope of the property itself, across getter and setter accessors.
Detailed design
Define contextual
auto
andfield
keywordMake
auto
andfield
contextual keywords inside property definition, whereauto
indifies a property will use exposed backing field, andfield
stands for the auto-generated backing field of a property.The
auto
should be a new contextual keyword, which is required becausefield
will come into conflict with any class member namedfield
.The
field
has already been a contextual keyword, though it's rarely seen in documents. See Attribute specification in C# specification. That means thefield
keyword won't appear in property definition context, so we can reuse it. And this also help to avoid involving one more new keyword.Backward compatible considerations
With the newly defined
auto
keyword, this change won't break existing code. Consider the following code:Without
auto
modifier in the property definition, thefield
will be explained as a usual identifier, and will be bound to the class memberfield
, which is a field here.With
auto
modifier, thefield
inside a property will be explained as keyword and be bound to the backing field of the property, while you can still usethis.field
to reference a class field.Semi-auto properties
Mostly, the getter of a property contains only one
return field;
statement, which is so boring. So we can leverage the triditional auto property syntax for only one of the accessors.And, may not that common, we can also define auto-setter-only property:
Note, since existing auto implemented property feature doesn't allow 'semi-auto' property, we can ommit
auto
modifier here, it's safe and won't break any existing code.Drawbacks
TBD
Alternatives
Option 1: define
UseBackingFieldAttribute
classInstead of involving new
auto
keyword, we can define a newUseBackingFieldAttribute
class, and use this attribute on the property which needs auto-generated backing field:This option involves new class definition, and emits attribute to the output assembly, which is unnecessary for runtime, and require the output assembly depends on the last version of .NET Framework.
Option 2: define
PropertyBackingFieldAttribute
classWe can also define a new
PropertyBackingFieldAttribute
class, and use this attribute on a field, to inform compiler that this field can only be accessed through property with the given name.But developer probably forget to add this attribute to the field. And again, the new class definition requires output assembly depends on last version of .NET Framework.
Unresolved questions
n/a
Design meetings
n/a
The text was updated successfully, but these errors were encountered: