The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both. The declarations take the following forms:
set {accessor-body} get {accessor-body}
where:
The body of the get accessor is similar to that of a method. It must return a value of the property type. The execution of the get accessor is equivalent to reading the value of the field. The following is a get accessor that returns the value of a private field name
:
private string name; // the name field public string Name { // the Name property get { return name; } }
When you reference the property, except as the target of an assignment, the get accessor is invoked to read the value of the property. For example:
Employee e1 = new Employee(); ... Console.Write(e1.Name); // The get accessor is invoked here
The get accessor must terminate in a return or throw statement, and control cannot flow off the accessor body.
The set accessor is similar to a method that returns void. It uses an implicit parameter called value, whose type is the type of the property. In the following example, a set accessor is added to the Name
property:
public string Name { get { return name; } set { name = value; } }
When you assign a value to the property, the set accessor is invoked with an argument that provides the new value. For example:
e1.Name = "Joe"; // The set accessor is invoked here
It is an error to use the implicit parameter name (value) for a local variable declaration in a set accessor.
A property is classified according to the accessors used as follows:
In a property declaration, both the get and set accessors must be declared inside the body of the property.
It is a bad programming style to change the state of the object by using the get accessor. For example, the following accessor produces the side effect of changing the state of the object each time the number
field is accessed.
public int Number { get { return number++; // Don't do this } }
The get accessor can either be used to return the field value or to compute it and return it. For example:
public string Name { get { return name != null ? name : "NA"; } }
In the preceding code segment, if you don't assign a value to the Name
property, it will return the value NA
.
This example demonstrates how to access a property in a base class that is hidden by another property with the same name in a derived class.
// Property hiding using System; public class BaseClass { private string name; public string Name { get { return name; } set { name = value; } } } public class DerivedClass : BaseClass { private string name; public new string Name { // Notice the use of the new modifier get { return name; } set { name = value; } } } public class MainClass { public static void Main() { DerivedClass d1 = new DerivedClass(); d1.Name = "John"; // Derived class property Console.WriteLine("Name in the derived class is: {0}",d1.Name); ((BaseClass)d1).Name = "Mary"; // Base class property Console.WriteLine("Name in the base class is: {0}", ((BaseClass)d1).Name); } }
Name in the derived class is: John Name in the base class is: Mary
The following are important points shown in the preceding example:
The property Name
in the derived class hides the property Name
in the base class. In such a case, the new modifier is used in the declaration of the property in the derived class:
public new string Name { ...
The cast (BaseClass)
is used to access the hidden property in the base class:
((BaseClass)d1).Name = "Mary";
For more information on hiding members, see the new modifier.
In this example two classes, Cube
and Square,
implement an abstract class, Shape
, and override its abstract Area
property. Note the use of the override modifier on the properties. The program accepts the side as an input and calculates the areas for the square and cube. It also accepts the area as an input and calculates the corresponding side for the square and cube.
// Overriding properties using System; abstract class Shape { public abstract double Area { get; set; } } class Square: Shape { public double side; // Constructor: public Square(double s) { side = s; } // The Area property public override double Area { get { return side*side ; } set { // Given the area, compute the side side = Math.Sqrt(value); } } } class Cube: Shape { public double side; // Constructor: public Cube(double s) { side = s; } // The Area property public override double Area { get { return 6*side*side; } set { // Given the area, compute the side side = Math.Sqrt(value/6); } } } public class MainClass { public static void Main() { // Input the side: Console.Write("Enter the side: "); string sideString = Console.ReadLine(); double side = double.FromString(sideString); // Compute areas: Square s = new Square(side); Cube c = new Cube(side); // Display results: Console.WriteLine("Area of a square = {0}", double.Format(s.Area, "0.00")); Console.WriteLine("Area of a cube = {0}", double.Format(c.Area, "0.00")); // Input the area: Console.Write("Enter the area: "); string areaString = Console.ReadLine(); double area = double.FromString(areaString); // Compute areas: s.Area = area; c.Area = area; // Display results: Console.WriteLine("Side of a square = {0}", double.Format(s.side, "0.00")); Console.WriteLine("Side of a cube = {0}", double.Format(c.side, "0.00")); } }
Enter the side: 4 Area of a square = 16.00 Area of a cube = 96.00 Enter the area: 24 Side of a square = 4.90 Side of a cube = 2.00
Properties | virtual | override | abstract | base | Indexers | new modifier