The standard method of implementing get and set accessors in C# and VB.NET is to use a public property to set and retrieve the value of a corresponding private variable. Am I right in saying that this has no effect of different instances of a variable? By this I mean, if there are different instantiations of an object, then those instances and their properties are completely independent right? So I think my understanding is correct that setting a private variable is just a construct to be able to implement the get and set pattern? Never been 100% sure about this.
1
You are correct up to this question:
So I think my understanding is correct that setting a private variable is just a construct to be able to implement the get and set pattern?
Quite the opposite is true. Ideally, only the encapsulating object should have direct access to the object(s) it encapsulates. This is known as the Law of Demeter.
In reality, following this “law” (like most programming laws) religiously can lead to over-engineering, but it is a very good principle to bear in mind.
Make the mental shift so you have to justify the existence of a getter, and separately a setter, before you blindly implement them for all private fields.
if there are different instantiations of an object, then those instances and their properties are completely independent
Yes, you are right.
So I think my understanding is correct that setting a private variable is just a construct to be able to implement the get and set pattern?
Not sure what you mean by that.
So I think my understanding is correct that setting a private variable is just a construct to be able to implement the get and set pattern?
It is not true. Private setters are encapsulating value and DO NOT allow direct access to the property of the class. It is one of the programming principles widely used in Domain driven development.
About this:
So I think my understanding is correct that setting a private variable
is just a construct to be able to implement the get and set pattern?
You can think of a property as a method that can do much more then just expose the underlying field. A property can also provide access to more than one private field.
For example, you could have an Invoice
which would have the TotalPrice
property.
This property would then return the sum of all Item
(which would be a List<Item>
property on the invoice) prices or something like that.
This way you are encapsulating the inner workings of the invoice and exposing just this simple property. In the get
method of the property, you could have various calls to other methods or properties to calculate the price.
The Item
could have private fields for price
and quantity
and a property Price
which would return (price * quantity)
. You could then add discount
to the mix, and the access to Price
from whatever is using the Item
would stay the same.
Moreover, you could make the property readonly (no set
method), where you can then change the item prices, but not the total directly, thus enforcing that the data is consistent.
I find it more helpful to think of properties as methods, rather than fields, and working with properties allows you to change how the data is returned without changing every call to that property (because you can process the field before returning, rather then outright giving the field to the client).
If you look at the Intermediate Language of the setter below:
private string _bar;
private string Bar
{
get
{
return this._bar;
}
set
{
this._bar = value;
}
}
Then you’ll see:
.method private hidebysig specialname instance string get_Bar() cil managed
{
// Irrelevant to this question
}
Now if you ignore everything within braces, you’ll see that it works similar to normal methods in your class. You can think of getters and setters as sugar syntax.
There is a whole separate discussion of when you should be using properties instead of methods, and what access modifier they should have, but it’s out of this question’s scope.
Finally, you class is just a blueprint. Once you instantiate an object from your blueprint (class), its logic is encapsulated, therefore accessing properties on this object doesn’t affect other objects that have been instantiated from the same class.
Reference: https://stackoverflow.com/questions/4184755/net-il-property-setter
OK sorry – on re-reading my question wasn’t 100% clear, so here’s the combined explanation on use of get/set to help others who want to know the rationale of using this pattern (thanks PDR – I’ve upvoted your response which was the most useful in constructing this explanation):
-
the get/set pattern in object oriented programming (including in .NET), is a pattern that looks like this (in VB.Net):
Private _Organisation As String Public Property Organisation() As String Get Return _Organisation End Get Set(ByVal value As String) _Organisation = value End Set End Property
-
The get/set pattern is used as a pattern that provides a structure that allows logic to be added during the setting or retrieval of a property instance of an instantiated class, which can be useful in various programming scenarios.
- If this pattern is implemented but no logic is actually performed in the ‘get’ or ‘set’ methods, the pattern can add unnecessary code which can constitute ‘over engineering’. It’s not a requirement for all properties to use the get/set pattern
- A property can have a ‘get’ accessor only, which is done in order to make that property read-only
- When implementing a get/set pattern, an intermediate variable is used as a container into which a value can be placed and a value extracted. The intermediate variable is usually prefixed with an underscore.
- this intermediate variable should be made private in order to ensure that it can only be accessed via its get/set calls and therefore more loosely coupled in the application (see the answer to this question from ‘pdr’ for more details)
- The intermediate variable is simply a technique that must be used when implementing a get/set pattern. Setting this intermediate variable has no effect on ‘protecting’ the variable across different instantiations of the objects- instances of an object and their property values are completely independent