C# Properties

A property is a (usually public) member of a class that provides (most commonly) a way to read or write the value of a private field or (less commonly) to compute a value from private fields. It is used by name as if it were a data member. It is, however, not a data member and cannot be passed as a ref or out parameter.

Here the terms get and set refer to accessors, properties used to read or write a value.

If we have a get accessor for a private field without a set accessor, the field is read-only. (Its value could still be changed by methods in the class but not simply by using an assignment statement in other code.) Likewise we could have a write-only field (a set accessor without a get accessor).

In the "set" accessor, the term "value" refers to whatever is on the right-hand side of an assignment statement. There could be logic in a set accessor; for instance, we could do range-checking and handle an out-of-bounds value by using an exception or a default value.

Properties can be declared as static (for instance, to provide access to a private static data member) and can be declared with any access specifier (for instance, perhaps the get accessor is public and the set accessor is more restricted).

Properties are widely used in C#. In the predefined classes, all the data members are private and we use only properties.

Again: It is commmon to list data members as private and provide properties for anything we want to make public.

There some limitations on properties. As a property is not a variable, it cannot be used as a ref or out parameter of a method.


Example adapted from a MSDN page:

     class TimePeriod
     {
      private double seconds;

     // Here are some properties.
      public double Seconds
      { 
       get { return seconds; }
       set { seconds = value; }
      }

      public double Minutes
      {
       get { return seconds / 60; }
      }

      public double Hours
      {
       get { return seconds / 3600; }
       set { seconds = value * 3600; }
      }
     }

     class Program
     {
      static void Main()
      { 
       TimePeriod t = new TimePeriod();  // default constructor

     // Assigning the Hours property causes the 'set' accessor to be called,
     // and it in turn calls the "set" accessor for seconds.
       t.Hours = 24;

     // Evaluating the Hours property causes the 'get' accessor to be called.
       System.Console.WriteLine("Time in hours: " + t.Hours);

       t.Seconds = 720;

     // Evaluating the Minutes property causes the 'get' accessor to be called.
       System.Console.WriteLine("Time in hours: " + t.Minutes);

     // Assigning the Seconds property causes the 'set' accessor to be called.
       Seconds = 4500;

     // Evaluating the Seconds property causes the 'get' accessor to be called.
       System.Console.WriteLine("Time in seconds: " + t.Seconds);
      }
     }

// Output:
// Time in hours: 24
// Time in minutes: 12
// Time in seconds: 4500

Notice that in this example, the property for working with "seconds" was called "Seconds" (first letter made upper case). These presumably do have to have different names; it is apparently conventional to make the names very similar. (Of course, anyone using the class would not normally be using the name of the private data member.)

Notice that we have properties called "Minutes" and "Hours" but there are no underlying variables for those values.

As Minutes" has a get accessor but no "set" accessor, it will be read-only.


Properties in an interface

It is possible to have properties in an interface. For example:

     public interface ISampleInterface
     {
     // Property declaration:
      string Name
      {
       get;
       set;
      }
     }

A class implementing the interface would need to have a data member of type string and define the get and set accessors for it.


Auto-implemented properties

It is possible to have auto-implemented properties which provide the get and set accessors. For example:

     class Customer
     {
     // Auto-Implemented Properties for trivial get and set
      public double TotalPurchases { get; set; }
      public string Name { get; set; }
      public int CustomerID { get; set; }
     // .. Additional methods, etc.
     }

The compiler will create private, anonymous fields of these types and default code for trivial get and set accessors.

Notice that in this case, we have data members in our own class which are so private that even we do not know their names. (This may seem somewhat absurd.)

If we wanted to have an auto-implemented property but not have a public set accessor, we could do the following:

     public double TotalPrice ( get; private set; }

This makes the get accessor public and the set accessor private. Only code inside the class's methods could set the value.


Expression Body Definitions

It is common to have properties that simply return immediately with the result of an expression. There is a syntax shortcut for defining these properties using the symbol =>:

     public string Name => First + " " + Last;

This is a get accessor, and you do not use the get accessor keyword. It is defined on one line using operators and does not use braces. The property will be read-only, as we cannot have a set accessor.