Properties In C#

Property in C#

Property in C# is a class member that exposes the class' private fields. Internally, C# properties are special methods called accessors. A C# property has two accessors, a get property accessor or a getter and a set property accessor or a setter. A get accessor returns a property value, and a set accessor assigns a new value. The value keyword represents the value of a property.

Properties in C# and .NET have various access levels defined by an access modifier. Properties can be read-write properties, read-only properties, or write-only properties. The read-write property implements both a get and a set accessor. A write-only property implements a set accessor but no get accessor. A read-only property implements a get accessor but no set accessor.

C# Properties

Internally, in a C# class, properties are nothing but a natural extension of data fields. Data encapsulation and hiding are the two fundamental characteristics of any object-oriented programming language. In C#, data encapsulation is possible through either classes or structures. By using various access modifiers like private, public, protected, internal, etc., it is possible to control the accessibility of the class members.

Usually, inside a class, we declare a data field as private and will provide a set of public SET and GET methods to access the data fields. This is a good programming practice since the data fields are not directly accessible outside the class. We must use the set/get methods to access the data fields.

An example, which uses a set of set/get methods, is shown below.

using System;

class MyClass
{
    private int x;
    public int X {
        get { return x; }
        set { x = value; }
    }
}

class MyClient
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        mc.X = 10;
        int xVal = mc.X;
        Console.WriteLine(xVal);
    }
}

The output from the above listing is shown below.

C# provides a built-in mechanism called properties to do the above.

In C#, properties are defined using the property declaration syntax. The general form of declaring a property is as follows.

{
    get{ }
    set{ }
}

Properties can be private, public, protected, or internal. In addition, properties can be any valid C# type. Note that the first part of the syntax looks quite similar to a field declaration, and the second part consists of a get accessor and a set accessor.

For example, the above code program can be modified with a property X.

class MyClass
{
    private int _x;
    public int X
    {
        get
        {
            return _x;
        }
        set
        {
            _x = value;
        }
    }
}

The object of the class MyClass can access property X as follows.

MyClass mc = new MyClass();
mc.X = 10; // calls set accessor of the property X, and pass 10 as value of the standard field 'value'.

This is used for setting the value for the data member x.

Console.WriteLine(mc.X);// displays 10. Calls the get accessor of the property X.

The complete program is shown below.

using System;

class MyClass
{
    private int _x;
    public int X
    {
        get
        {
            return _x;
        }
        set
        {
            _x = value;
        }
    }
}

class MyClient
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        mc.X = 10; // Setting the value of the property
        int xVal = mc.X; // Retrieving the value of the property
        Console.WriteLine(xVal); // Displays 10
    }
}

Remember that a property should have at least one set or get an accessor. The set accessor has a free variable called value, which gets created automatically by the compiler. Therefore, we can't declare any variable with the name value inside the set accessor.

We can do very complicated calculations inside the set or get an accessor. Even they can throw exceptions.

Since normal data fields and properties are stored in the same memory space, in C#, it is impossible to declare a field and property with the same name.

Static Properties

C# also supports static properties, which belong to the class rather than to the objects of the class. All the rules applicable to a static member also apply to static properties.

The following program shows a class with a static property.

using System;

class MyClass
{
    private static int _x;
    public static int X
    {
        get
        {
            return _x;
        }
        set
        {
            _x = value;
        }
    }
}

class MyClient
{
    public static void Main()
    {
        MyClass.X = 10; // Setting the value of the static property
        int xVal = MyClass.X; // Retrieving the value of the static property
        Console.WriteLine(xVal); // Displays 10
    }
}

Remember that set/get accessor of the static property can access only other static members of the class. Also, static properties are invoked by using the class name. Check out Working With Static In C# (c-sharpcorner.com) to learn more about static in C#.

Properties and Inheritance in C#

A derived class can inherit the properties of a base class.

using System;

class Base
{
    public virtual int X
    {
        get
        {
            Console.Write("Base GET");
            return 10;
        }
        set
        {
            Console.Write("Base SET");
        }
    }
}
class Derived : Base
{
}
class MyClient
{
    public static void Main()
    {
        Derived d1 = new Derived();
        d1.X = 10; // calls the set accessor of the Base class
        Console.WriteLine(d1.X); // calls the get accessor of the Base class
    }
}

The output from the above listing is shown below.

The above program is very straightforward. The inheritance of properties is just like the inheritance of any other member. Check out Object Oriented Programming In C# (c-sharpcorner.com) to learn more about inheritance in C#.

Properties and Polymorphism in C#

A Base class property can be polymorphically overridden in a Derived class. But remember that the modifiers like virtual, override, etc., are used at the property level, not at the accessor level.

//C# : Property : Polymorphism
//Author: [email protected]
using System;

class Base
{
    public virtual int X
    {
        get
        {
            Console.Write("Base GET");
            return 10;
        }
        set
        {
            Console.Write("Base SET");
        }
    }
}

class Derived : Base
{
    public override int X
    {
        get
        {
            Console.Write("Derived GET");
            return 10;
        }
        set
        {
            Console.Write("Derived SET");
        }
    }
}

class MyClient
{
    public static void Main()
    {
        Base b1 = new Derived();
        b1.X = 10;
        Console.WriteLine(b1.X);
    }
}

The output from the above listing is shown below.

Check out Understanding Polymorphism In C# (c-sharpcorner.com) for more details.

Abstract Properties

A property inside a class can be declared as abstract by using the keyword abstract. Remember that an abstract property in a class carries no code at all. For example, the get/set accessors are represented with a semicolon. In the derived class, we must implement both sets and get assessors.

If the abstract class contains only a set accessor, we can implement only a set in the derived class.

The following program shows an abstract property in action.

//C# : Property : Abstract
//Author: [email protected]
using System;

abstract class Abstract
{
    public abstract int X { get; set; }
}

class Concrete : Abstract
{
    public override int X
    {
        get
        {
            Console.Write(" GET");
            return 10;
        }
        set
        {
            Console.Write(" SET");
        }
    }
}

class MyClient
{
    public static void Main()
    {
        Concrete c1 = new Concrete();
        c1.X = 10;
        Console.WriteLine(c1.X);
    }
}

The output from the above listing is shown below.

The properties are important features added at the language level inside C#. They are instrumental in GUI programming. Remember that the compiler generates the appropriate getter and setter methods when it parses the C# property syntax.

Property Access Modifiers in C#

Access modifiers define the access level of a property, whether a property can be accessed by any caller program, within an assembly, or just within a class.

The following table describes access level modifiers.

  • Public - Any other code can access the type or member in the same assembly or another assembly that references it.
  • Private - The type or member can be accessed only by code in the same class or struct.
  • Protected - The type or member can be accessed only by code in the same class or in a class that is derived from that class.
  • Internal - The type or member can be accessed by any code in the same assembly but not from another assembly.
  • Any code can access protected internal - The type or member in the assembly in which it is declared or from within a derived class in another assembly.
  • Private protected - The type or member can be accessed only within its declaring assembly, by code in the same class, or in a type derived from that class.

Automatically Implemented Properties in C#

A typical implementation of a public property looks like a listing. The default implementation of a property needs a getter and setter.

private string name;

public string Name
{
    get { return this.name; }
    set { this.name = value; }
}

Auto-implemented properties in C# make code more readable and clean if no additional calculation is needed. For example, the above listing code can be replaced by the following line.

public string Name { get; set; }

The compiler creates a private field variable in auto-implemented properties that can only be accessed through the property's getter and setter.

The code listed in the listing is a class with several auto-initialized properties.

using System;
class Author
{
    // Read-write properties
    public string Name
    {
        get;
        set;
    }
    public string Publisher
    {
        get;
        set;
    }
    public string Book
    {
        get;
        set;
    }
    public Int16 Year
    {
        get;
        set;
    }
    public double Price
    {
        get;
        set;
    }
    public string PriceInString
    {
        get
        {
            return string.Format("${0}", Price);
        }
    }
    // Read-only properties
    public string Names
    {
        get;
    }
    // Initialization of a property
    public double AuthorCount
    {
        get;
        private set;
    } = 99;
    // Class constructor
    public Author(string name, string publisher, string book, Int16 year, double price)
    {
        Name = name;
        Publisher = publisher;
        Book = book;
        Year = year;
        Price = price;
    }
    // Public methods
    public string AuthorDetails()
    {
        return string.Format("{0} is an author of {1} published by {2} in year {3}. Price: ${4}", Name, Book, Publisher, Year, Price);
    }
    public double CostOfThousandBooks()
    {
        if (Price > 0) return Price * 1000;
        return 0;
    }
}

The code in the listing creates an instance of the class and calls its methods and properties.

class Program
{
    static void Main()
    {
        Author author = new Author("Mahesh Chand", "Apress", "Programming C#", 2003, 49.95);
        Console.WriteLine(author.AuthorDetails());
        Console.WriteLine("Author published his book in {0}", author.Year);
        author.Price = 50;
        Console.WriteLine(author.CostOfThousandBooks().ToString());
        Console.ReadKey();
    }
}

Auto Property Initializers

To initialize a property value of a class, we used to set the property value in a class constructor. In the code listed in Listing 1, the Name property of the Author class is initialized in the class’s constructor. 

class Author
{
    public string Name { get; set; }
    public string Book { get; set; }
    public double Price { get; set; }

    public Author()
    {
        Name = "Mahesh Chand";
    }    
}

Listing 1.

C# 6,0 introduces auto property initializers that allow you to set the default value of a property during the declaration in a class. The code listed in Listing 2 initializes the Name property value during the declaration.

class Author
{
    public string Name { get; set; } = "Mahesh Chand";
    public string Book { get; set; }
    public double Price { get; set; }

}

Listing 2.

Default Value of A Getter Only Property

We can make class properties read-only by removing their setter accessor. In the code snippet in Listing 1, the Author class declares three read-only properties, Name, Book, and Price.

class Author
{
public string Name { get; }
public string Book { get; }
public double Price { get; }
}

Listing 1

Making a setter accessor private allows a class to access the property within the defined class but makes it read-only when accessed from outside of the defined class. Listing 2 declares the Book and Price properties read-only from outside by making their setter accessor private and protected.

class Author
{
    public string Name { get; set; } = "Mahesh Chand";
    public string Book { get; private set; } = "C# Programming";
    public double Price { get; protected set; } = 45.95;
}

class Program
{
    static void Main()
    {
        Author author = new Author();       
        Console.WriteLine("Author {0}, book {1}, price {2}", 
            author.Name, author.Book, author.Price);
       
        Console.ReadKey();
    }
}

Listing 2

Summary

Properties are integral to an object-oriented programming language such as C#. In C#, properties have read-write, read-only, and write-only types. C# properties also support various accessors to provide accessibility levels. In this article, you learned about properties in C#. You saw how a property is declared and used in a C# program. You also saw how to declare read-only and write-only properties. You also learned static properties, auto-implemented properties, and abstract properties. 


Similar Articles