C#. Properties. Accessors get, set. Examples of classes containing properties

C#. Properties. Accessors get, set. Examples of classes containing properties


Contents



1. The concept of property. General form. Accessors get, set

A property is a special class field containing a program code for accessing internal variables (fields) of a class or calculating a certain value. Properties provide a convenient and rational way to access the internal variable in the class.

 The general form of property in a class

type PropName {
    get {
        // code to read the internal field (variable)
        // ...
    }
    set {
        // code to write the value in the internal field (variable)
        // ...
    }
}

here

  • type – the type that the property returns;
  • PropName – property name. This name refers to the property;
  • get – an accessor that is used to read the value from the internal field of the class;
  • set – the accessor used to write the value to the internal field of the class. The set accessor receives an implicit parameter value containing the value that is assigned to the property.

If the property name is found on the right side of an assignment statement or in an expression

variable = obj.PropName; // get

get is then called. Here obj is the name of the instance of the class in which the PropName property is declared.

If the property name is found on the left side of the assignment operator

obj.PropName = expression; // set

then the set accessor is called. Here obj is the name of the instance of the class in which the PropName property is declared.

 

2. The advantages of using the properties in classes

Using properties in classes provides the following advantages:

  • more rational and natural access to internal class variables is provided;
  • in the accessor code, you can implement all sorts of checks on the validity of the values of the internal variables of the class;
  • flexibility of access rights to an internal variable: the absence of a set accessor allows for read-only access for internal class data. This, in turn, makes it impossible to accidentally change this data.

 

3. An example of a property that implements a read/write variable of type int

The example demonstrates a simple case of accessing a property in a class. A class is declared with the name IntNumber in which the following are implemented:

  • internal hidden (int) variable of type int named d;
  • a constructor with one parameter that initializes the variable d;
  • property named Number. This property contains get and set accessors;
  • method Display() for displaying the value of the hidden variable d.

The text of the class IntNumber and its use in the main() function are as follows (application of the Console Application type)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp7
{
  // the simplest example of a class that uses properties
  class IntNumber
  {
    private int d;

    // constructor
    public IntNumber(int _d)
    {
      d = _d;
    }

    // a property declaration named Number
    private int Number
    {
      // reading the field d
      get
      {
        return d;
      }

      // write value to d field
      set
      {
        d = value;
      }
    }

    // display of d field on the screen
    public void Display()
    {
      Console.WriteLine("d = {0}", d);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // declare an instance number of class IntNumber
      IntNumber number = new IntNumber(5);

      // print the value of the internal variable d
      number.Display(); // d = 5

      // change the value of d through the property Number.set
      number.Number = 25;
      number.Display(); // d = 25

      // use property Number.get to read d
      int t;
      t = number.Number; // t = 25
      Console.WriteLine("t = {0}", t);
    }
  }
}

The result of the program

d = 5
d = 25
t = 25
Press any key to continue . . .

 

4. How do access specifiers to class elements (private, public) affect property access?

To use a property, it must be declared in the public section. If the property is declared with the access specifier private, then this property will be unavailable. As a result, when trying to access a property, the compiler will give an error message.

ClassName.PropName is inaccessible due to its protection level

where PropName is the name of the private property declared in the ClassName class.

 

5. An example of a property that implements access to an internal variable, which is an array of double

The example declares an ArrayDouble class that implements an array of real numbers. The class declares:

  • internal hidden (private) variable A, which is an array of double;
  • two class constructors;
  • an indexer that returns an element of an array at a given index;
  • property Sum, which defines accessors get and set.

The text of the class ArrayDouble and its use in the main() method, the following

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp7
{
  // array of type double
  class ArrayDouble
  {
    double[] A; // array of numbers of double type

    // class constructors
    public ArrayDouble(int size)
    {
      // allocate memory for the array
      A = new double[size];

      // fill the array with zeros
      for (int i = 0; i < size; i++)
        A[i] = 0.0;
    }

    public ArrayDouble(double[] _A)
    {
      // allocate memory for array
      A = new double[_A.Length];

      // copy one array to another
      for (int i = 0; i < _A.Length; i++)
        A[i] = _A[i];
    }

    // indexer
    public double this[int index]
    {
      get
      {
        if ((index >= 0) && (index < A.Length))
          return A[index];
        else
          return 0.0;
      }
    }

    // Property Sum:
    // get - determines the sum of the elements of the array
    // set - allocates elements in the array with equal values
    public double Sum
    {
      get
      {
        // calculating the sum of the elements
        double s = 0;
        for (int i = 0; i < A.Length; i++)
          s += A[i];
        return s;
      }
      set
      {
        // uniform distribution of the elements of array A by value
        double v = value/A.Length;
        for (int i = 0; i < A.Length; i++)
          A[i] = v;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      double[] X = { 1.0, 2.5, 2.0, 4.5, 0.0 }; // array
      ArrayDouble ad = new ArrayDouble(X); // create an instance of the class ArrayDouble
      double sum; // sum of elements
      sum = ad.Sum; 
      Console.WriteLine("sum = {0}", sum);

      // fill the array in the ad instance with the values 1.0
      ad.Sum = 1.0 * X.Length;

      // checking
      double t;
      t = ad[2]; // t = 1.0
      Console.WriteLine("t = {0}", t);
    }
  }
}

In the ArrayDouble class, the Sum property is implemented. This property defines two get and set accessors. For the purpose of demonstration, the accessor get implements the calculation of the sum of the elements of array A

...
public double Sum
{
  get
  {
    // calculating the sum of the elements
    double s = 0;
    for (int i = 0; i < A.Length; i++)
      s += A[i];
    return s;
  }
  ...
}
...

Using the set accessor, the value/A.length value is entered into each item of array A

...
set
{
  // uniform distribution of the items of array A by value
  double v = value/A.Length;
  for (int i = 0; i < A.Length; i++)
    A[i] = v;
}
...

Conclusion: in get, set accessors it is possible to set additional operations of calculation on class data. It is not necessary to return the value of some field in the class.

The result of the program

sum = 10
t = 1
Press any key to continue . . .

 

6. An example of a property that implements access to a structure variable (struct)

The example demonstrates accessing a structure of the Fraction type using properties. Properties are declared in the Complex class, which implements a complex number. The Complex class declares the following elements:

  • internal hidden (private) variables real, imag. These variables (fields) correspond to the real and imaginary parts of the complex number;
  • the Real property for reading/writing the value of the real field;
  • the Imag property for reading / writing the value of the imag field;
  • the RealD property, representing the real field value as a real number of double type. This property is read-only (get), the set accessor is not in the property;
  • the ImagD property, representing the value of the imag field as a real number of double type. This property is read only (get);
  • the Abs property that calculates the modulus of a complex number. This property is read only.

The program text for an application of the Console Application type is as follows

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp7
{
  // the structure, realizing fraction
  struct Fraction
  {
    public int num; // numerator
    public int denom; // denominator
  }

  // class implementing a complex number
  class Complex
  {
    private Fraction real; // real part of a complex number as a fraction
    private Fraction imag; // imaginary part of a complex number as a fraction

    // constructors
    public Complex(int _real, int _imag)
    {
      real.num = _real;
      real.denom = 1;
      imag.num = _imag;
      imag.denom = 1;
    }

    public Complex(Fraction _real, Fraction _imag)
    {
      real = _real;
      imag = _imag;
    }

    // property corresponding to the real part of a complex number
    public Fraction Real
    {
      get
      {
        return real;
      }
      set
      {
        real = value;
      }
    }

    // property corresponding to the imaginary part of a complex number
    public Fraction Imag
    {
      get
      {
        return imag;
      }
      set
      {
        imag = value;
      }
    }

    // property that returns the real part of a complex number
    // in the form of type double
    public double RealD
    {
      get
      {
        return (double)real.num / (double)real.denom;
      }
    }

    // property that returns the imaginary part of a complex number
    // in the form of type double
    public double ImagD
    {
      get
      {
        return (double)imag.num / (double)imag.denom;
      }
    }

    // property that returns the modulus of a complex number
    public double Abs
    {
      get
      {
        double t,r,i;
        r = real.num / (double)real.denom;
        i = imag.num / (double)imag.denom;
        t = Math.Sqrt(r * r + i * i);
        return t;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      Fraction r = new Fraction();
      Fraction i = new Fraction();
      r.num = 3;
      r.denom = 1;
      i.num = 4;
      i.denom = 1;

      Complex cm = new Complex(r, i); // create an instance of class Complex

      // property Abs
      double abs = cm.Abs; // get a modulas, abs = 5
      Console.WriteLine("Abs = {0}", abs);

      // properties RealD, RealI
      double rd, id;
      rd = cm.RealD; // rd = 3/1 = 3.0
      id = cm.ImagD; // id = 4/1 = 4.0
      Console.WriteLine("rd = {0}", rd);

      // property Real
      Fraction R = new Fraction();
      R = cm.Real; // R = { 3, 1 }
      Console.Write("R.num = {0},   ", R.num);
      Console.WriteLine("R.denom = {0}", R.denom);
    }
  }
}

The result of the program

Abs = 5
rd = 3
R.num = 3, R.denom = 1
Press any key to continue . . .

 

7. An example of a property that implements access to a class object

The example demonstrates access to a class object using a property.

The class Point is declared, that implement a point on the coordinate plane. The class declares:

  • two internal hidden (private) variables x, y which are the coordinates of a point;
  • two constructors;
  • properties X, Y. These properties with accessors get, set access to the hidden variables x, y.

The Line class is also declared, which implements a line consisting of two points of type Point. The class implements:

  • private internal variables p1, p2 of type Point. These are the points of the ends of the segment;
  • properties P1, P2 that implement access to internal variables p1, p2. These properties return of a class object of type Point;
  • the Length property, which defines the length of the line. This property contains only one accessor get. The accessor set is missing.

The text of the demo program created using the Console Application template is as follows

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp7
{
  // a class that implements the line
  class Point
  {
    private float x;
    private float y;

    // constructors
    public Point()
    {
      x = y = 0f;
    }

    public Point(float _x, float _y)
    {
      x = _x;
      y = _y;
    }

    // properties
    public float X
    {
      get { return x; }
      set { x = value; }
    }

    public float Y
    {
      get { return y; }
      set { y = value; }
    }
  }

  // class that implements a line
  class Line
  {
    // internal data - line points, objects of class Point
    private Point p1;
    private Point p2;

    // constructor
    public Line(Point _p1, Point _p2)
    {
      p1 = new Point();
      p1.X = _p1.X;
      p1.Y = _p1.Y;
      p2 = new Point(_p2.X, _p2.Y);
    }

    // properties
    public Point P1 // get the first point of the line
    {
      get { return p1; }
      set { p1 = value; }
    }

    public Point P2 // get the second point of the line
    {
      get { return p2; }
      set { p2 = value; }
    }

    // the property that determines the length of the line,
    // contains only one accessor get
    public double Length
    {
      get
      {
        double len;
        len = Math.Sqrt(p1.X * p1.X + p2.Y * p2.Y);
        return len;
      }
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // access to class object using property
      // create instances of the class
      Point p1 = new Point(2, 4);
      Point p2 = new Point(6, 8);
      Line line = new Line(p1, p2);

      // demonstration of the P1, P2 properties of Line class
      Point p3, p4;
      p3 = line.P1; // acsessor get
      p4 = line.P2;
      float x, y;
      x = p3.X; // x = 2
      y = p3.Y; // y = 4
      Console.WriteLine("x = {0},   y = {1}", x, y);

      p3.X = -3;
      p3.Y = -1;
      line.P1 = p3; // acsessor set
      Console.WriteLine("x = {0},   y = {1}", line.P1.X, line.P1.Y);

      // print the length of the line using the Length property
      double length;
      length = line.Length;
      Console.WriteLine("Length = {0}", length);
    }
  }
}

As can be seen from the above code, the Line class implements two properties that access an object of the Point class

...
// properties
public Point P1 // get the first point of the line
{
  get { return p1; }
  set { p1 = value; }
}

public Point P2 // get the second point of the line
{
  get { return p2; }
  set { p2 = value; }
}
...

The result of the program

x = 2, y = 4
x = -3, y = -1
Length = 8.54400374531753
Press any key to continue . . .

 

8. Is memory space allocated for properties?

No, it doesn’t. Properties control access to fields. The property itself does not represent the field (data member) of the class. The field must be defined in the class regardless of the property.

 


Related topics