-
Notifications
You must be signed in to change notification settings - Fork 4k
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: Introduce hidden backing store for complex properties in C#. #7614
Comments
TL;DR version: Don't wanna have to define a backing field for a slightly-more-complicated-than-an-auto-property, so add contextual identifier In my opinion I don't see a big need for this. Encapsulation is controlled by the type, not the members within the type. The rest of the complaints are completely valid and serve to indicate problems with tooling. |
The syntax Because of that, I think #850 is better. As another advantage, it lets you specify the type of the backing field (e.g. to use |
This proposal (as well as #850) advocates for an enhanced level of encapsulation, which I feel could be very useful. Consider how you would communicate to your team of developers that they must use the setter for property Consider why we even have the Same applies here. Prevent mistakes early, instead of finding them once the system is well into production. |
Even with that argument I would certainly prefer #850 over this proposal. This proposal would create a form of identifier otherwise completely alien to the C# language. It also seeks to change the charter of auto-implemented properties which were designed specifically to make property-declaration more concise when no additional logic is required in the property accessors. |
@HaloFour Agreed. |
Yet another way of making backing fields local to properties. I compile-time-only attributes are introduced, this can be achieved by an analyzer.
|
Me too, I don't really see a big advantage over #850 here. Only makes things fuzzier an not so clear to read. |
Regarding #850. This person is talking about an anonymous class. That's the logical equivalent of a lambda function. Think of it as a lambda class. When a basic property is credited, the compiler creates a hidden field to hold the data. I just want that field exposed within the property. It is not an inner class. It is an encapsulated field. This is what properties should be, but without any data leakage. A property is not syntactic sugar. It is a design a pattern. The guiding principle behind creating a property is to encapsulate an attribute of a class (such as height and weight), to control data access, to ensure the state is always valid, and to notify listeners of updates. Only by exposing the backing store internally can this principle be taken to its logical conclusion. Finally, the reason I reject the other suggestion is because it violates the S.O.L.I.D. design pattern for properties. For the record, lambda classes do have value. Normally, an inner class is created, instantiated, and then exposed through a field. A lambda class makes sense here, since only one instance of the class is needed. However, from a design point of view, properties and lambda classes are separate entities and must not be confused. Here is my suggestion of how both would look.
With lambda classes, you would have
Regarding @svick comment about it being unC#ish, $state isn't much different than the 'this' keyword and the 'value' keyword we already use. Just like 'value', $state is scoped to just the property. As I mentioned before, having an external data store only breaks encapsulation. |
How about 'self' as backing store. More C-like than $state. We already have an implicit variable here: 'value'. public MyType MyProperty { |
Using a backing field without naming it was considered in https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-04-01.md |
1. Background
In computer programming the state of an object is stored in data fields. This allows callers to view and modify the state of the object at will.
This had two drawbacks:
To overcome the above problems, some people use 'get' and 'set' methods to hide the underlying field. This was cumbersome and unnatural. As a result, C# introduced properties.
2. C# Properties
C# properties encapsulate the state of an object, as seen by external callers. The external caller could now reference the state of an object in a more natural way, while still ensuring a consistent state.
With properties you can:
3. Problem
Unfortunately, with standard properties we have four problems:
Example:
For work I was required to create a WPF application with data binding. As a result, I had to create model classes that had no real functionality other than to store property definitions, and a way to update the UI when a property changed.
Therefore, C# properties don't encapsulate state in any object oriented way.
There is an exception to this:
With this construct, the compiler creates a hidden field that holds the state. Unfortunately, this is little more than a field with a few added benefits.
As a work-around, I created a custom base class to manage state: http://www.codeproject.com/Articles/875224/Encapsulating-property-state-in-MVVM-WPF-applicati.
4. C# Properties – With state encapsulation
To enable true OOP properties, we need to be able to encapsulate state. I would like to propose a possible way of encapsulating state.
Dedicated keyword: $state
We can introduce a keyword to represent state. The compiler creates a hidden private class-level field to store the state.
The keyword $state is only valid within the body of a get or set.
Used within the class, it would look like this:
Note: The compiler only creates the hidden field when the $state keyword is used.
5. Conclusion
This is not a replacement for private fields.
Instead, this is for times when:
The text was updated successfully, but these errors were encountered: