Mech_Engineer
Mech_Engineer

Reputation: 555

Class Property implementation styles

I'm trying to learn more about programming, in particular object orientated programing.

I have a book that explains how to create properties but they also combine it with a private variable. I can't understand why they do this, and what the advantage of doing this would be.

Here is a sample code.

Namespace PropertyExample
Class Person
    Private _Name As String
    Public Property Name() As String
        Get                                                            ' (1)
            Name = _Name
        End Get
        Set(ByVal value As String)                                     ' (2)
            _Name = value
        End Set
    End Property
End Class

I another example they write it like this, which is alot cleaner is my opinion.

Class Person
    Public Property Name() As String
End Class

Upvotes: 1

Views: 46

Answers (3)

Alex B.
Alex B.

Reputation: 2167

  1. The first approach you mention was the only way properties could be written until .NET 3.5.

  2. The second one is called Auto-Implemented Property and was introduces with C# 3.0/.NET 3.5.

Internally, also the auto-implemented property uses a private variable to store the data. It´s only syntactic sugar added by the compiler to save the developer a bit of time and make the code more readable.

Why to use a visible declared variable instead of using just the auto-implemented property?

Well, this depends on the context of your program. If you just want a 1:1 public mapper for a name variable you can go with the auto-implementation.

If, however, there is some logic needed when setting/getting the value of the variable you have to use the extra variable approach.

Assume you got the requirement that the Names in your app must not be greater than 50 chars. You could handle this validation in the setter of your property:

    Set(ByVal value As String)
         If value.Length <= 50                      
           _Name = value
         Else 
            'Throw some validation error
         End if
    End Set

This can only be done if you defined an variable (here _Name). It´s not possible to do that with an auto-implemented property.

If you are interested in details:

Both of your code snippets produce (almost) the same MSIL:

Person.get_Name:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldfld       UserQuery+Person._Name
IL_0007:  stloc.0     // Name
IL_0008:  br.s        IL_000A
IL_000A:  ldloc.0     // Name
IL_000B:  ret         

Person.set_Name:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldarg.1     
IL_0003:  stfld       UserQuery+Person._Name
IL_0008:  nop         
IL_0009:  ret     

vs.

Person.get_Name:
IL_0000:  ldarg.0     
IL_0001:  ldfld       UserQuery+Person._Name
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

Person.set_Name:
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  stfld       UserQuery+Person._Name
IL_0007:  nop         
IL_0008:  ret

As you can see both snippets read/write their string values in a varibale _Name (stfld). (The only diff is the nop command which is used while debugging and can be ignored here.)

Upvotes: 1

which is alot cleaner is my opinion

The latter are called auto-implemented properties. The compiler supplies the backing field for which can reduce boiler plate code. You can still reference a _Name private member in your code.

Better/cleaner depends. You need the full version for situations like this:

Public ReadOnly Property Age As Integer
    Get
        If DateOfBirth <> DateTime.MinValue Then
            Return (DateTime.Now.Year - DateOfBirth.Year)
        Else
            Return 0
        End If
    End Get
End Property

A similar example would be a Read-Only Count property on a collection class. Or:

Private _name As String = ""
Public Property Name As String
    Get
        Return _name
    End Get
    Set(value As String)
        If _name.ToLowerInvariant <> value.ToLowerInvariant Then
            _name = value
            NotifyPropertyChanged()
        End If
    End Set
End Property

There are times when the auto implement version cant be used. As a book, I would expect it to cover/show both ways at least for those who have an older version of VS.

Auto Implemented properties became available in VS 2010; the NET Framework version doesn't matter since it is a compiler feature.

Upvotes: 1

Claudius
Claudius

Reputation: 1911

The reason for private variable is to be only accessed within this class. When you look closely you will see property being called Name and variable called _Name. It is a naming convention and you should use it. That variable shouldn't be accessed even from same class from anything else than that property.

That said property is public to be accessed from different classes and projects.

You presented the common look of property:

Private _Name As String
Public Property Name() As String
    Get                                                            ' (1)
        Name = _Name
    End Get
    Set(ByVal value As String)                                     ' (2)
        _Name = value
    End Set
End Property

Other inlude readonly, writeonly:

Private _Name As String
Public ReadOnly Property Name() As String
    Get                                                            ' (1)
        Name = _Name
    End Get
End Property

Another good example would be:

Private _Name As String
    Public ReadOnly Property Name() As String
    Get                                                            ' (1)
        If Strinf.IsnullOrEmpty(_Name)
           _Name = Somemethod()
        End if
        Return _Name
    End Get
End Property

This property gets initialized when first time being used.

Upvotes: 1

Related Questions