Reputation: 555
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
Reputation: 2167
The first approach you mention was the only way properties could be written until .NET 3.5.
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
Reputation: 38875
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
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