Automatically implemented properties

WARNING: This is a speculative post. Caveat emptor.

I apologize for the long silence, things have been a little busy around Panopticon Central these days! Anyway, I wanted to go back to talking about some of the things that we’re thinking about for the next version, and I thought I’d go over a small one: automatically implemented properties. As the name implies, these would be basically the same thing you get in C# 3.0’s auto-implemented properties.

What we’re talking about is allowing you to have a simple property declaration like so:

Public Property x() As Integer

This would generally expand under the covers to look something like this:

Private _x As Integer
Public Property x() As Integer
    Get
        Return _x
    End Get
    Set(ByVal value As Integer)
        _x = value
    End Set
End Property

The one major difference that we’re considering from C#’s auto-implemented properties is to allow initializers on the auto-implemented property. In other words, something like:

Public Property x As Integer = 10
Public Property y As New List(Of Integer)()

I think C# also doesn’t let you bind to the underlying field, but just like with other auto-generated stuff in VB, I think we’d err on the side of allowing you to bind to it if you really needed to. You can also make them Overridable if you like, to allow derived classes to provide their own implementation.

Just a little feature, but one that can be useful.

35 thoughts on “Automatically implemented properties

  1. Greg

    Please make both C# and VB.NET work the same in this respect. C# and VB.NET should become closer over time and nearly identical at some well in the future date.

    Simplifying the languages would help alot since shops I’ve worked at inherited lots and lots of consultant written code that shows that the consultant never ever ever has to dogfood (live with) their own code for any length of time.

    Example: A consultant tasked with writing a straightforward small report went off and built a 20+ object data model, loaded SQL data into the model and then (in horribly unmaintainable code) use Reflection to generate the report by recursing through the object model. We’re watching carefully any future uses of reflection.

    We’re a shop with 500,000+ lines of VB.NET, C#, ASP.NET and TSQL stored procedures.

    Reply
  2. MarcelDevG

    Uh, Please do NOT make C# and VB.NET work the same.

    Let them challenge each other πŸ™‚

    I can see your point in mulit language shops and consultants leaving behind code that doesn’t comply.

    But for Automatically Implemented properties, what is the use. My propertie functies mostly do a bit more than only return a local value or setting a local value.

    You can just make the variable global instead?

    Or am I missing the point ?

    Reply
  3. Ninputer

    Can the compiler differentiate an auto property or an incomplete normal property declaration?

    I suggest VB’s property declaration can explicitly define the Get/Set procedure instead of new keywords such like ReadOnly, that could avoid lot’s of problems.

    ‘An auto generated property:

    Public Property Foo As String With {Get, Set}

    ‘An auto generated property with private setter:

    Public Property Foo As String With {Get, Private Set}

    ‘An abstract property has different accessor visibility:

    Public MustOverride Property Foo As String With {Get, Protected Set}

    ‘An interface property, but the user want to add custom attribute:

    Property Property Foo As String With {Get, <Obsolete>Set}

    Reply
  4. Kyralessa

    Yes! Yes! We want it! πŸ™‚ It pains me to have auto-implemented properties in C#, but not VB. I was very surprised that it didn’t make it into VB 2008…though inline XML kind of makes up for it.

    And I say, give VB cool features that C# doesn’t have. VB gets the shaft so often that it’s only fair that it occasionally get something cool, like the aforementioned inline XML, that C# can’t do yet.

    And also, I still would love to see the option for lower-case keywords.

    Reply
  5. Pingback: @ Head

  6. Klaus Even Enevoldsen

    Cool, it is a good idea. 9 out of 10 of all the properties I write could be replaced by automatically implemented properties.

    Initializers would be cool too. Do it soon and let us have a CTP πŸ™‚

    Reply
  7. Tim

    I was very disappointed when i heard auto properties were not in VB2008.

    I would love that feature, the number of times i have had to add 30 properties (slight exaggeration) to a class and adding the local variables and such, even the property snippit is tedious doing that (not to mention turning 300 lines into 30 making it much easier to read)

    The binding and initializer parts are especially nice.

    However (in VB2005)

    Public Property x() As Integer

    Expands to

    Public Property x() As Integer

    Get

    End Get

    Set(ByVal value As Integer)

    End Set

    End Property

    (ie no local variable)

    Which is how it should probably be. Would it not be nicer to say

    Public Auto Property x() As Integer

    Or something like that (so that it wont auto complete the rest of the property ? Or am i being too verbose ? (im one of the few that doesn’t mind lots of keywords in a language).

    What would be really nice is if you added it into .Net 3.5 SP1 or earlier because (i assume) its just a compiler thing and the generated MSIL would be identical to if we wrote the property the long way.

    Reply
  8. Steve

    Yes! Love it love it love it.

    They syntax looks great and consistent with declaring a field, even the initialization.

    Reply
  9. Konrad

    After an initial euphoria, I don’t think these auto-implemented properties are such a cool thing after all. I tend to make a lot of backing fields read-only to underline the fact that these never have to change once assigned. Unfortunately, this can’t be done with C#’s auto-implemented properties; you have to at least give it a private setter.

    The VB auto-implemented properties seem to suffer from the same drawback, initializers don’t change that greatly. Will I be able to write the following code?

    Class Foo

    Public ReadOnly Property Name() As String

    Public Sub New(name As String)

    _name = name ‘ Should work

    End Sub

    Public Sub SetName(name As String)

    _name = name ‘ Should most emphatically *not* work

    End Sub

    End Class

    I know it’s rather a small concern but it does wonders to self-documenting code.

    Reply
  10. Pingback: ??????

  11. Csaba

    Hi all,

    In principle good with Auto properties.

    (Anyhow I’m for KISS so I use fields as properties in VB)

    Even nicer if also possible to have as as Konrad suggest:

    Public ReadOnly Property Name() As String

    As MarcelDevG wrote: "Let them (C# & VB) challenge each other πŸ™‚ "

    And let Cobra challange C# & VB!

    @Konrad: if this should not work:

    Public Sub SetName(name As String)

    _name = name ‘ Should most emphatically *not* work

    End Sub

    what code should then work? Of course you must be able to set the private internal field indirectly. Or are you considering protected fields (instead of private)?

    Reply
  12. Konrad

    Csaba: This code should only work in the constructor or the initializer and nowhere else, analogously to ‘ReadOnly’ fields currently supported in VB:

    Class Foo

    Private ReadOnly m_Value1 As String = "Hello" ‘ Works

    Private ReadOnly m_Value2 As String

    Public Sub New()

    m_Value2 = "World" ‘ Works

    End Sub

    Public Sub ChangeValue(ByVal v As String)

    m_Value1 = v ‘ Error: ‘ReadOnly’ variable cannot be target of an assignment

    End Sub

    End Class

    I know this is a tiny detail and that I’m one of the only people to use it that way – but if it’s not to be used in this way, then why have ‘ReadOnly’ fields in the first place? I thinkt this is a great way of documenting one’s code and also of reflecting one’s own design: in a well-thought design variables tend to rarely change values. I like the way Nemerle does it (although I wouldn’t suggest this for VB): here, any variable is read-only unless explicitly marked ‘mutable’.

    Reply
  13. RichB

    VB Classic (v4-6) implemented public member variables as property get/set pairs at the COM level. ie VB6 had automatically implemented properties. How does this proposal differ?

    Reply
  14. simon geering

    Well coderush does exactly this for me today with only needing to type three or four characters so i for one don’t mind what you chose to use πŸ™‚

    It is that sort of tooling enhancements rather than changes at the language level that provide a better trade of between flexibility and productivity. Having too many options in the language just means we end up having to learn more different ways of doing the same thing!

    As Greg points out that is all very interesting from an academic point of view until you have to support it in the real world, and come across yet another mad hatter form of coding in the project your havint to take ownership of.

    Reply
  15. Kevin

    I, from time to time visit this site in order to check whether or not VB has caught up to c#, this post has once again answered that question.

    Can you imagine a VB developer jumping up from his work station somewhere in some company, surrounded by c# developers and rejoicing at the top of his voice that VB is finally getting auto-implemented properties, haha what a laugh, how can vb be regarded as a professional language. Can’t we finally "can" it and get developers to join the c# team.

    Reply
  16. Fervent Coder

    I have to say that I am in agreeance with Konrad, although I am thinking along the lines of Ninputer. I do like the syntax for the Autoset.

    My suggestions however are like this:

    #1

    Public Property FirstName() As String

    ‘The default when you want both an auto get and set

    Public Property Address() As String [Get]

    ‘ ReadOnly

    Public Property City() As String [Set]

    ‘ Write Only

    Public Property Id() As Integer [Get] = 0

    ‘ Readonly with default

    Public Property LastName() As String [Get, Protected Set]

    ‘ Still allowing your class to call the setter outside of the constructor

    OR #2:

    Public Property FirstName() As String

    Public Property LastName() As String

    Get

    Protected Set

    End Property

    OR #3:

    Public Property FirstName() As String

    ‘ The default when you want both an auto get and set

    Public Readonly Property Address() As String

    ‘ ReadOnly

    Public WriteOnly Property City() As String

    ‘ Write Only

    Public ReadOnly Property Id() As Integer = 0

    ‘ Readonly with default

    <ProtectedSet()>

    Public Property LastName() As String

    ‘ Still allowing your class to call the setter outside of the constructor

    @Konrad:

    ‘To alleviate the confusion of calling _name or _lastName in this case (which is nowhere to be found). You are also specifying an internals naming preference (which I share, but others do not).

    <ProtectedSet()>

    Public Property LastName() As String

    ‘ Still allowing your class to call the setter outside of the constructor

    Public Sub New(lastName as string)

    Me.LastName = lastName

    End New

    I am much a fan of the first or third suggestions here. The third seems the most straightforward with the easiest adoption. The point I am getting to here is that we don’t want to lose Protected Setters.

    Reply
  17. Fervent Coder

    Perhaps that would be better as

    <ProtectedSet()>

    Public ReadOnly Property LastName() As String

    ‘ Still allowing your class to call the setter outside of the constructor

    Reply
  18. Anthony D. Green

    I’d prefer to stick with using ReadOnly/WriteOnly to specify the absence of setters and getters. Breaking from that would be pointless in my opinion.

    Regarding protected sets and ReadOnly backing fields – I’m a big fan of attribution in lieu of new keywords in some situations. The language already supports attributes so I would guess the effort would be less. Also this would be a good reason to expand the attribute targetting support in VB to match or exceed C#’s. This is a real boost for those of us who need to make NonSerialized event fields.

    The only problem with this whole scheme is settling on the naming convention for the backing field. I suppose I’d be dreaming if this were configurable on a per project basis.

    Good luck differentiating between these and an incomplete property declaration for the current auto-insertion behavior. Perhaps this is a time to embrace a smart-tag based refactoring to promote an auto property to a standard property.

    Reply
  19. Konrad

    @Fervent Coder: nice touch, that would actually do that.

    Concerning the naming convention I must admit that I hate this style and only adopted it here because it was used in Paul’s post. I personally don’t like leading underscores because they somehow screw with my sense of indentation, plus they lead to problems in other environments (generally, a leading underscore screams at me “stuff the compiler put here”). I’ve adopted the ‘m_’ convention in VB6 and I still use it for .NET and C++.

    So, in conclusion, this somehow proves your point.

    Reply
  20. Anthony D. Green

    Aye, I personally hate the m_ convention but far be it for me to legislate another coder’s private fields.

    Reply
  21. Greg

    I’d suggest trying to solve the problem by making a static member function do the work.

    This is from my experience seeing vb.net code with many function calls made in this order:

    a = new object_X

    a.set_property_Y = 5

    a.set_Property_Z = 6

    a.method_call()

    a.dispose

    a = nothing

    versus the static function call method

    object_X.method_call(X = 5, Y = 6)

    The static member function will be easier to maintain and debug since it requires no (object creation, set properties) warmup and no shutdown (destructor).

    It also can be freely moved around your application without significant side effects.

    Reply
  22. Branco Medeiros

    Having some form of shortcut for property declaration would be great.

    What bothers me is an automatic name being generated behind the scenes.

    In my ideal language, a shortcut to declaring properties would allow the specification of both the underlying variable name and the actual property name independently. It also would allow me to specify distinct access modes for Get and Set, or to have a ReadOnly or WriteOnly property, or even to make one access implicit and the other explicit:

    Class SomeClass

    ‘—————

    ‘Get and Set default to Public access

    Private _X As Integer Get, Set X

    ‘—————

    ‘variable name and property name are

    ‘independent of each other;

    ‘also, both Get and Set may have

    ‘distinct access modes

    Private _SomeVar As String Get, Protected Set Text

    ‘—————

    ‘Read-only and write-only properties

    ‘are just a keystroke away

    Protected mName As String ReadOnly Name

    Private mStats As Double WriteOnly Stats

    ‘—————

    ‘auto Get, explicit Set

    Private mAge As Integer Get Age

    ‘the dreaded "Property Set" syntax

    ‘makes a comeback

    Public Property Set Age(Value As Integer)

    If Value < 0 OrElse Value > 120 Then

    ‘… throw suitable error

    ‘…

    End If

    End Property

    End Class

    Reply
  23. Greg

    One caution: making everything a property and framework building are done at the expense of solving the business problem.

    Reply
  24. Ivan Gusev

    I don’t think auto-properties are good, because you cannot insert custom code in them. If you cannot insert custom code in them, they behave precisely like public fields – why make them properties then?

    Maybe if this autogeneration could be extended by attributes (i.e. GetterOnly, or RaiseEventOnChange), it would be worth implementing.

    Reply
  25. Anthony D. Green

    It’s important to realize that these nice-to-have supplemental language features are not meant to address every usage scenario imaginable. Attempting to do so only creates an inelegant solution that satisfies no one. This is a feature that makes a specific and simple scenario – implementing the simplest possible property – appropriately simple. 80% of developers need nothing more than this 80% of the time during initial development. It does not and should not replace the existing property syntax which allows greater control as needed for more explicit requirements such as raising events and attribution and such. The syntax to support the breadth and depth of possibilities often equals or exceeds the code you could have typed with the traditional syntax anyway.

    Why would you want to do this rather than expose public fields?

    #1, You can’t data-bind to a field. The framework infrastructure is pretty biased towards properties and the GUI tools won’t even look for them.

    #2, Fields can’t be specified in Interfaces.

    #3, Versioning – field access is compiled differently than property access – changing a field to a property necessarily breaks any existing client and requires a rebuild.

    #4, OOP Encapsulation forbids exposing private state (i.e. fields) publicly. This may seem like a stupid reason to some but others (myself included) take it very seriously for a lot of the reasons above.

    Bottom line this kind of feature removes the tax developers have to pay to follow best practices by making it cheap to do so – so that it DOES NOT come at the expense of solving the business problem. It’s a great feature, KISS.

    Reply
  26. Elijah

    I just thought of something after looking at some of my code.

    Public WithEvents Property Foo as New SomeObject

    This code would declare the private field using the WithEvents keyword.

    It would be nice to be able to use the other keywords that one can now use when declaring a property; Overridable and such.

    Reply
  27. Kathleen Dollard

    Paul,

    I know I’ve said this to you separately, but I’d like to say it publically here. Do not add auto-implemented properties unless they can be mixed scope, or at the very least Readonly in the sense of a readonly property and a writable backing field. I realize there are a minefield of issues on this, and I think its great that some good syntax has been thrown out in comments here.

    The importance of Readonly properties lies parially in the best practice and FxCop rule that object properties rarely be writable and collection properties almost never so.

    In C# you can’t write to the backing field because there are zero scenarios for doing so (unless in serialization, and honestly I haven’t explored those isseus). Do NOT make the backing field accessible unless there’s a good reason to do so, or you make the expansion code not break when someone has accessed the field. Allowing an expansion to break code is unacceptable.

    And I think you are chasing the wrong rainbow. Provide an answer for simplifying dependency properies and you offer value.

    Reply
  28. Fervent Coder

    @Kathleen Dollard: I agree 100% with the mixed scope. I

    have been thinking about my first comments and I think I could live with the following idea, which is very simple yet effective:

    Public Class Bill

    Public ReadOnly Property FirstName() As String

    Public Sub ChangeFirstName(ByVal name As String)

    FirstName = name

    End Sub

    End Class

    Public Class Bob

    Private _bill As Bill

    Public Sub New()

    _bill = New Bill()

    ‘ works because accessing the getter

    dim firstName As String = _bill.FirstName

    ‘ does not compile because accesses the setter, which is only available to the implementing class

    _bill.FirstName = "ERROR"

    End Sub

    End Class

    Any ReadOnly or WriteOnly Property only has that functionality OUTSIDE encapsulation. Outside the implementing class. Inside the implementing class it behaves just like a property you can both set and get.

    Reply
  29. CodeJoy

    Do it! Do it! (chanting)

    Automatic properties would be awesome! They would make code easier to read and navigate.

    At least add (what I would consider to be) the basic automatic properties.

    ‘ auto getter and setter

    Property Name As String

    ‘ auto getter

    ReadOnly Property Age As Integer

    And I really like the property initializer idea and Overridable modifier!

    Also I agree with Tim. Release with SP1 πŸ™‚

    Reply
  30. Pingback: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *