Table of Contents (top down ↓)
Example of a Property
Consider this program. I have attached it as a download to this video. Let me explain it line by line.
First we have a data member that stores the amount. This member is private so it is not directly accessible from outside. This member stores the actual data but it is not accessible from outside the class.
After this we have a property called Amount
. This property is public. Take note of the syntax - braces contain the getter and setter functions. The get
accessor provides access to the backing member of this property. We have an opportunity of modifying the data before making it available to the caller. In this code we have returned the actual value.
The set method receives data in the value keyword. The incoming data is therefore contained in the value
keyword.
The set method makes a validity check. If the validation fails, then it throws an exception. Thus, the setter ensures that invalid data doesn't enter an object.
class Program { // backing member for the property private int _amount; // property public int Amount { get { return _amount; } set { if( (value < 0) || value > 1000) { throw new ArgumentOutOfRangeException("value"); } _amount = value; } } static void Main() { Program p = new Program(); // set p.Amount = 20; // get Console.WriteLine($"Amount = {p.Amount}"); } }
This code can be made better.
Notice that it contains a magic figure of 1000. Experts say that such figures should be avoided. They affect the readability of your program.
Notice also that there is a magic string called "value" in the code that throws the exception. This string is the keyword "value" in double quotes.
We can make the following two changes -
- Replace 1000 by a const int - const int MAX_AMOUNT = 1000;
- Replace the string by using a
nameof
expression -nameof(value)
. The nameof expression gives the name of an identifier as a string constant.
With these two changes the code becomes more systematic as you can see here. The constant MAX_AMOUNT gives a readable meaning to the magic figure of 1000. Another advantage is that if the figure has to be changed in future, then the change needs to be made just at one place, and the whole code gets updated wherever this figure is used.
class Program { // a constant to avoid hard-coded // values in the program const int MAX_AMOUNT = 1000; // backing member for the property private int _amount; // property public int Amount { get { return _amount; } set { if( (value < 0) || value > MAX_AMOUNT) { throw new ArgumentOutOfRangeException(nameof(value)); } _amount = value; } } static void Main() { Program p = new Program(); // set p.Amount = 20; // get Console.WriteLine($"Amount = {p.Amount}"); } }
Video Explanation (see it happen!)
Please watch the following youtube video:
Auto Implemented Property Syntax
If the getter and setter make no validation, then there is no need to specifically add a backing member.
In this code there is no backing member for the Amount
property. Observe also that we only mentioned the keywords get
and set
. The compiler generated everything else for us.
Notice also that it is possible to mark public, private, etc., accessibilty on a setter or getter as per requirements.
class Program { // property one liner auto implemented public int Amount { get; private set; } static void Main() { Program p = new Program() { Amount = 20 }; // get Console.WriteLine($"Amount = {p.Amount}"); } }
A more Comprehensive Example and Initialization of Objects
Let's look at an example which demonstrates various types of properties.
The first property is an auto-implemented property that has been initialized at declaration.
The second property, Item, is a read only property because no setter has been given. A readonly property can be initialized either at declaration or in a constructor.
After that we have an init only property called ISBN. This property can be intialized once only. It can be initialized at any time - such as at declaration, during constructor, and even after the object has been created. The only restriction is that it can be initialized atmost once.
Lastly, we have the main function. Properties ISBN and Name have been initialized using a special syntax of curly braces. The two properties have been separated by a comma.
class Program { public string Name { get; set; } = String.Empty; // readonly must be init at declaration // or in a constructor, but NOT later public string Item { get; } = "motor"; // init-only, can be set atmost once // at declaration, constructor, any point later // or never, unless marked required public string ISBN { get; init; } static void Main() { Program p = new Program() { ISBN = "3278", Name = "C# Language" }; // display Console.WriteLine($"{p.Name}, {p.ISBN}, {p.Item}"); } }
Try to solve the attached exercises for a hands-on practice on this syntax.
Similar Posts
This Blog Post/Article "(C# Language) Properties Auto-Implemented, Init, Readonly, Required" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.