Skip to content
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

Implicit property backing fields #196

Closed
AnthonyDGreen opened this issue Nov 1, 2017 · 7 comments
Closed

Implicit property backing fields #196

AnthonyDGreen opened this issue Nov 1, 2017 · 7 comments

Comments

@AnthonyDGreen
Copy link
Contributor

AnthonyDGreen commented Nov 1, 2017

Trying to eliminate some redundancy (and work) when declaring expanded properties. I propose that given this declaration:

Property P As T
    Get

    End Get
    Set(value As T)

    End Set
End Property

There is an implicit backing field named _P of type T that is property scoped (see #195).

  • It is only created if no field of that name exists already.
  • It is only emitted if it's referred to in either the getter or the setter.

So nothing would change about existing property declarations today but this broken code (assuming no field _P actually exists):

Property P As T
    Get
        Return _P
    End Get
    Set(value As T)
        _P = value
    End Set
End Property

Would compile under this proposal. This eliminates repeating the name P and the type T which makes changing both much easier. We could use a magic keyword to mean "the implicit backing field" like Field or _Value but why go through all of that when the convention for backing fields is pretty well known. Also, we want the maintain the convention that we use for auto-prop backing fields for binary serialization reasons. Convention over Configuration FTW!

@reduckted
Copy link
Contributor

I'm not sure I understand what this proposal is trying to achieve. 😕

Both of the examples you've shown could be simplified with an auto-property. Are you suggesting that in cases where an auto-property is not sufficient (because you need to do other things in, for example, the setter), that the backing field is auto-generated?

@AnthonyDGreen
Copy link
Contributor Author

That's correct, @reduckted. Of course, if you don't use it, it it's won't make your objects bigger. The purpose is to reduce the amount of code you need to write for properties that you wouldn't express as auto-props, without having to type the name of the property twice, or repeat its type.

@reduckted
Copy link
Contributor

reduckted commented Nov 3, 2017

Cool 👍

the convention for backing fields is pretty well known.

🤔 Hmm, not so sure about this. Given that it's previously been a hidden compiler detail, I'm not sure it's that well known. Plus a quick look at the roslyn repo shows that the convention is actually camel-case instead of pascal-case. For example:

Given that there are varying conventions, maybe the backing field could be declared as part of the property signature. Something like this, maybe:

Property Name As String WithBacking _name
    Get
        Return _name
    End Get
    Set
        _name = Value
    End Set
End Property

At least it's a bit more obvious to newcomers where the backing field comes from instead of just being this magic symbol (though the Value parameter has the same problem and I have no problem with that 😁). I'm not sold on the keyword, but Using or With would be overloading those keywords, and I'm not sure that's a great idea.

An alternative to having some magic backing field symbol would be to use the property name itself (though that's likely to be a breaking change). Function names are already defined as implicitly returned locals in functions (not that I'm fond of that), so why not use the same concept here. For example:

Property Name As String
    Get
        Return Name
    End Get
    Set
        Name = Value
    End Set
End Property

When compiled, the use of the property name inside the getter and setter would translate into the usual compiler-generated backing field that auto-generated properties get.

@rskar-git
Copy link

There is an implicit backing field named _P of type T that is property scoped (see #195).

I would much prefer that the backing field be scoped to the Class or Module of the property, in much the same way it's done now for a property without Get or Set block.

The only use-case I can see for this property scoped field concept is to put window-dressing on a field, so that one can do value checks within the setter, maybe some aspect-oriented stuff in the getter, and have it all be part of an Interface. Which seems real nice until the day comes you'd like to do some sort of re-initialization without kicking off any side-effects of the setter; or find yourself really stuck in the case of a ReadOnly Property. Meanwhile, within the Class or Module that defines the Property, CPU cycles are wasted on getter and setter calls.

Mostly I see alot of bad habits down the road...

@Bill-McC
Copy link

Bill-McC commented Nov 4, 2017

What happens if I do a symbolic rename on _P ? Likewise what happens if I rename P, do all the _P's get changed ?
I think if you implement #195, then a code expansion that shows generated code as per #199 , would work better. Plus it would help with #194 or #198 when you want to modify bindable properties.

@AnthonyDGreen
Copy link
Contributor Author

AnthonyDGreen commented Dec 7, 2017

Update: The 11/15/2017 LDM rejected this idea. In short, we just didn't like it.

@jrmoreno1
Copy link

@reduckted : I know this is a dead issue at this point, but in regards to it being well known...I would say it is, as it’s how you do the equivalent of C# T P {get; private set;}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants