Property
In C#, the concept of Property is a crossover concept of Field and Method. It means that it includes the features of field and method combined. In C#, property is a class member that is used to expose a field (which is used to hold data) of a class to another class. More exactly, Property is an extension of Method construct used to expose field of a class.
For each field of a class, a separate property is needed to deal with the field.
Before understanding concept of property, let us understand that what are the shortcomings or limitations with field, which led to the development of property as language construct.
A class is composed of data and methods that deal with the data. In a class, the first part is the data which is related to the fields and the second part is about the methods working on the data. Fields of a class are implicitly private by default. This means that data or field is private by default in a class and no other class can access that private field. If a class wants to access field of another class, then the access modifier of the field should be explicitly declared public. But this is against the principle of Data Hiding or Data Encapsulation.
Reason for fields being by default private in C#
Each field of class is kept private by default so that that field or its data is protected and cannot be manipulated by another class. If a class's field is public, then any class can manipulate that field. But in most cases, as per business requirement, we do not want to keep the field of the class public because exposing data publicly is vulnerable for mishandling. In other words, we want to prevent the field or data of class from being used directly by another class. In such a situation we have to make that field private. This is the reason fields are by default private in C#.
Property to expose private fields of a class
Now one possibility is that by keeping the field private, we do not give the right to access it directly to another class, but at the same time we should take some such measures due to which it is possible to access that private field by another class, so and for this, property as language construct have been developed in C#.
Property as special method
Although private fields can be exposed through public method even without property, but if you expose private field with the help of public method, then there is a possibility that another class can override or overload that method, etc., but a property is a language construct that is created for the specific purpose of exposing the private field. There can be overriding of properties like methods but properties cannot be overloaded in C#. A property is accessed simply by its name. There is no argument list for the compiler to use to distinguish between multiple properties named Name. Therefore, the behavior of the property, despite being like a method, is different and can be considered as a special form of method.
Main Points:
- Property can be overidden like a method in derived class.
- But Property cannot be overloaded like a method.
- Property has get and set blocks to do two distinct jobs - getting value of its field and setting value of its field. Method has no such specific job for fields (But if desired, Getter and Setter methods can be created for these two distinct jobs). Methods are used for many other jobs.
- The set block of property is used to set value for a field. The constructor of class can do this job as well. Separate set blocks are needed to set different fields of class but a single constrctor can be used to set different fields. Note that constrctor is a special kind of method for initializing the fields at runtime.
- Property can initialize its field at compile time and runtime both.
- The get and set blocks are by default public but can be given other modifiers such as private and protected also.
Getter and Setter Methods
Private fields can be exposed through public method even without property, the example of which is given below -
namespace PropertyEx
{
class Employ
{
string name;
int age;
//constructor
public Employee(string name, int age)
{
this.name = name;
this.age = age;
}
//method to get name field
public string GetName()
{
return name;
}
//method to set name field
public void SetName(string Name)
{
this.name = Name;
}
//method to get age field
public int GetAge()
{
return age;
}
//method to set age field
public void SetAge(int Age)
{
this.age= Age;
}
}
}
using System;
namespace PropertyEx
{
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Amitabh", 15);
Console.WriteLine("Original name: "+ e1.GetName());
Console.WriteLine("Original age: " + e1.GetAge().ToString());
e1.SetName("Amit");
e1.SetAge (41);
Console.WriteLine("New name: " + e1.GetName());
Console.WriteLine("New age: " + e1.GetAge().ToString());
Console.ReadKey();
}
}
}
In C#, a property is a special type of programming construct or method that allows to get or/and set fields of a class. Property enables the safe use of data under C# programming.
A property is a programming construct in C# that consists of get blocks or/and set blocks. Within the get block, we provide the logic to get a field. Similarly, within the set block, we write the logic according to which another class can modify the value of a field of class. So, a property is a language construct with the help of which a private field of a class can be obtained or its value can be modified another class. It is to be remembered that a property class contains the logic of getting or/and setting of the field. For example, if a class has three private fields then we have to provide three different properties for these three private fields within the class.
Property Definition Rules
To declare the property of any field we should follow the following syntactic rules
- The name of the property should match the name of the field so that it can be understood which field this property is for. For example, the name field of the property Name is appropriate.
- The datatype of both the fields whose property is to be created should be same. For example, the datatype of the name field is string, then the datatype of the property Name will also be string.
- The access modifier of the property should be given public so that it can be accessed by any other class. We can also use other access modifiers such as protected; this is decided keeping in mind the needs of the business.
- A property block is denoted by { } like a class block. {} Property blocks contain get blocks and set blocks.
- Within the get and set block, the field of the class whose property get is set is used. There is a return statement within the get block whereas within the set block there is a contextual keyword called value.
- Even get and set accessors can be given access modifier. By default the access modifier of get and set are that of its property.
- Validation logic can be used inside get block before returing the value of property. The validation logic will be before return statement inside get block.
- Validation logic can be used inside set block before setting the value of property.
- Validation logic can use local variables, if and switch statements inside get and set blocks.
- This is possible inside get and set blocks because they are just extension of methods. We can almost do anything inside get and set blocks that are possible inside a method.
Example of Property Definition is Employee class
namespace PropertyEx
{
class Employee
{
string name;
int age;
//constructor
public Employee(string name, int age)
{
this.name = name;
this.age = age;
}
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
}
}
using System;
namespace PropertyEx
{
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Amitabh", 15);
Console.WriteLine("Original name: "+ e1.Name);
Console.WriteLine("Original age: " + e1.Age.ToString());
e1.Name = "Rakesh";
e1.Age = 30;
Console.WriteLine("New name: " + e1.Name);
Console.WriteLine("New age: " + e1.Age.ToString());
Console.ReadKey();
}
}
}
It is not mandatory for a field within a class to have a property. If the field of a class is public then there is no need to create a property for that field.
Property is always created in relation to a field of the class. A property is related to one and only one field of the class.
If the field of a property is not explcitly given in class then the field will be generated by compiler. For example, if property name is Age then implicit field by name _age will be generated by the complier. Internally, compiler also generates getter and setter methods e.g. GetAge and SetAge for implicit field _age for property Age.
A property can only contain a get block or only a set block, or it can contain both get and set blocks.
- When the property contains only get block then such property is called readonly property.
- When the property contains only set block then such property is called writeonly property.
- When a property contains get and set blocks, such a property is called a readwrite property.
In C#, the return statement is always used in the get block of the property, while the value keyword is always used in the set block. The value keyword is a contextual keyword used to set a value in a field.
Convention of Naming Property
It is not necessary to define a property for all the fields within a class. If field is public then it is useless to define property for public fields. Property should be defined for private field so that it could be accessed in other classes via its Property. Property name must be in Pascal case. If field name is _age then property name will be Age.
Purposes of Property
1) The main purpose of a property is to limit or restrict the direct access to a class's field. Fields can be accessed via properties.
2) Another purpose of a property is to conditionally restrict access to a class's field. For example, access to a field of a class can be done with a get condition or a set condition, or both a condition. The validation logic can be placed inside set block to allow only valid values for setting value of property. Similarly, validation logic can be placed inside get block before returning the value of property.
Example of conditional access
namespace PropertyEx
{
class Employee
{
string name;
int age;
//constructor
public Employee(string name, int age)
{
this.name = name;
this.age = age;
}
public string Name
{
get { return name; }
set
{
if (value != null && value.Length > 0)
{
name = value;
} }
}
public int Age
{
get { return age; }
set
{
if (value > 18 )
{
age = value;
} }
}
}
}
using System;
namespace PropertyEx
{
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Amitabh", 15);
Console.WriteLine("Original name: "+ e1.Name);
Console.WriteLine("Original age: " + e1.Age.ToString());
e1.Name = "Ajay";
e1.Age = 27;
Console.WriteLine("New name: " + e1.Name);
Console.WriteLine("New age: " + e1.Age.ToString());
Console.ReadKey();
}
}
}
Example of Properties get accessor and set modifier behave like methods.
Properties are full-fledged, first-class C# language elements that are an extension of methods that access or modify internal data. We can define local variables inside get and set accessors. They are completely isolated from other code. An example is given below in this regard. Both get and set accessors have their own local variable defined with same name without any name conflict. You can use if and switch statements inside get and set blocks.
class Program
{
private int _number;
public int Number
{
get
{
int localVariable = 100;
return _number + localVariable;
}
set
{
int localVariable = 200;
if (value < localVariable)
{
_number = value;
}
else
{
_number = localVariable;
}
Console.WriteLine($"You can define local variable inside property: {localVariable}");
}
}
static void Main(string[] args)
{
Program program = new Program();
program.Number = 1;
Console.WriteLine(program.Number);
program.Number = 300;
Console.WriteLine(program.Number);
}
}
Example of Properties protected set modifier
public class Customer
{
public virtual string Name
{
get; // public
protected set;
}
// remaining implementation omitted
}
class Program
{
static void Main(string[] args)
{
Customer customer= new Customer();
// Error: The property or indexer 'Customer.Name' cannot be used in this context
// because the set accessor is inaccessible
customer.Name = "Ajeet";
}
}
Example of overriding Properties
The following is example of auto-implemented property overidden in derived class. But if you don't want to use auto-implementation, then you can use a private field for Name field, as shown in next section code.NOTES:
- The overridden property must have the same type (string?).
- The accessor accessibility cannot be changed.
- Since the base property has get → public and set → protected then the overidden property will have get → public and set → protected also.
- If set block has protected or private modifier then the derived class should use parameterized constructor to set the value of property. The derived class can even use Setter method for setting the value of property.
public class Customer
{
public virtual string? Name
{
get; // public
protected set;
}
}
public class RegularCustomor : Customer
{
public overide string? Name
{
get; // public
protected set;
}
The following example shows how you can override an autoimplemented property without using auto-implementation in derived class.
Note that constructor with parameter is used to set the value for property.Example Using Auto-Implented Virtual Property in Base class & Non-Auto-Implented Override Property
public class Customer
{
public virtual string? Name
{
get; // public
protected set;
}
}
public class RegularCustomor : Customer
{
private string? _name;
public RegularCustomor(string? name)
{
_name = name;
}
public override string? Name
{
get { return _name; }
protected set { _name = value; }
}
}
class Program
{
static void Main(string[] args)
{
RegularCustomor customer = new RegularCustomor("Ajeet");
Console.WriteLine("Read property value: " + customer.Name);
}
}
Example Using Auto-Implented Virtual Property
public class Customer
{
public virtual string? Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.Name = "John Doe";
Console.WriteLine(customer.Name);
}
}
Example Using Auto-Implented Property & Overide Propertypublic class Customer
{
public virtual string? Name { get; set; }
}
public class SpecialCustomer : Customer
{
public override string? Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
SpecialCustomer customer = new SpecialCustomer();
customer.Name = "John Doe";
Console.WriteLine(customer.Name);
}
}
Example Using Auto-Implented Property with Private set blockpublic class Customer
{
public string? Name { get; private set; }
public Customer(string? name)
{
this.Name = name;
}
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer("John Doe");
Console.WriteLine(customer.Name);
}
}
Example Using Auto-Implented Property with Protected set blockpublic class Customer
{
public string? Name { get; protected set; }
public Customer(string? name)
{
this.Name = name;
}
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer("John Doe");
Console.WriteLine(customer.Name);
}
}
Example Using Auto-Implented Property with Protected set block & Setter Methodpublic class Customer
{
public string? Name { get; protected set; }
public void SetName(string? name)
{
this.Name = name;
}
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.SetName("John Doe");
Console.WriteLine(customer.Name);
}
}
Example Using Auto-Implented Property with Protected set block & Constructorpublic class Customer
{
public string? Name { get; protected set; }
public Customer(string? name)
{
this.Name = name;
}
}
public class RegularCustomer
{
public string? Name { get; protected set; }
public RegularCustomer(string? name)
{
this.Name = name;
}
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer("John Doe");
Console.WriteLine(customer.Name);
RegularCustomer rcustomer = new RegularCustomer("Ajeet Kumar");
Console.WriteLine(rcustomer.Name);
}
}

No comments:
Post a Comment