37 out of 55 rated this helpful - Rate this topic

Using Properties (C# Programming Guide)

Properties combine aspects of both fields and methods. To the user of an object, a property appears to be a field, accessing the property requires exactly the same syntax. To the implementer of a class, a property is one or two code blocks, representing a get accessor and/or a set accessor. The code block for the get accessor is executed when the property is read; the code block for the set accessor is executed when the property is assigned a new value. A property without a set accessor is considered read-only. A property without a get accessor is considered write-only. A property with both accessors is read-write.

Unlike fields, properties are not classified as variables. Therefore, it is not possible to pass a property as a ref (C# Reference) or out (C# Reference) parameter.

Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields.

Properties are declared within the class block by specifying the access level of the field, followed by the type of the property, followed by the name of the property, then a code block declaring a get-accessor and/or a set accessor. For example:

public class Date
{
    private int month = 7;  //"backing store"

    public int Month
    {
        get
        {
            return month;
        }
        set
        {
            if ((value > 0) && (value < 13))
            {
                month = value;
            }
        }
    }
}

In this example, Month is declared as a property so that the set accessor can make sure the Month value is set between 1 and 12. The Month property uses a private field to track the actual value. The real location of a property's data is often referred to as the property's "backing store." It is common for properties to use private fields as a backing store. The field is marked private in order to make sure it can only be changed by calling the property. For more information about public and private access restrictions, see Access Modifiers (C# Programming Guide).

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. For example, when you are returning the private variable from the get accessor and optimizations are enabled, the call to the get accessor method is inlined by the compiler so there is no method-call overhead. However, a virtual get accessor method can not be inlined since the compiler does not know at compile-time which method may actually be called at run time. The following is a get accessor that returns the value of a private field name:

class Person
{
    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:

Person p1 = new Person();
//...

System.Console.Write(p1.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.

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.

private int number;
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:

class Employee
{
    private string name;
    public string Name
    {
        get
        {
            return name != null ? name : "NA";
        }
    }
}

In the preceding code segment, if you do not assign a value to the Name property, it will return the value NA.

The set accessor is similar to a method whose return type is 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:

class Person
{
    private string name;  // the name field
    public string Name    // the Name property
    {
        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:

Person p1 = new Person();
p1.Name = "Joe";  // the set accessor is invoked here                

System.Console.Write(p1.Name);  // the get accessor is invoked here

It is an error to use the implicit parameter name, value, for a local variable declaration in a set accessor.

Properties can be marked as public, private, protected, internal, or protected internal. These access modifiers define how users of the class can access the property. The get and set accessors for the same property may have different access modifiers. For example, the get may be public to allow read-only access from outside the type, and the set may be private or protected. For more information, see Access Modifiers (C# Programming Guide).

A property may be declared as a static property using the static keyword. This makes the property available to callers at any time, even if no instance of the class exists. For more information, see Static Classes and Static Class Members (C# Programming Guide).

A property may be marked as a virtual property using the virtual keyword. This allows derived classes to override the property behavior using the override keyword. For more information about these options, see Inheritance (C# Programming Guide).

A property overriding a virtual property can also be sealed, specifying that for derived classes it is no longer virtual. Lastly, a property can be declared abstract, meaning there is no implementation in the class, and derived classes must write their own implementation. For more information about these options, see Abstract and Sealed Classes and Class Members (C# Programming Guide).

NoteNote

It is an error to use a virtual (C# Reference), abstract (C# Reference), or override (C# Reference) modifier on an accessor of a static property.

This example demonstrates instance, static, and read-only properties. It accepts the name of the employee from the keyboard, increments NumberOfEmployees by 1, and displays the Employee name and number.

public class Employee
{
    public static int NumberOfEmployees;
    private static int counter;
    private string name;

    // A read-write instance property:
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    // A read-only static property:
    public static int Counter
    {
        get { return counter; }
    }

    // A Constructor:
    public Employee()
    {
        // Calculate the employee's number:
        counter = ++counter + NumberOfEmployees;
    }
}

class TestEmployee
{
    static void Main()
    {
        Employee.NumberOfEmployees = 100;
        Employee e1 = new Employee();
        e1.Name = "Claude Vige";

        System.Console.WriteLine("Employee number: {0}", Employee.Counter);
        System.Console.WriteLine("Employee name: {0}", e1.Name);
    }
}

Employee number: 101

Employee name: Claude Vige

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.

public class Employee
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

public class Manager : Employee
{
    private string name;

    // Notice the use of the new modifier:
    public new string Name
    {
        get { return name; }
        set { name = value + ", Manager"; }
    }
}

class TestHiding
{
    static void Main()
    {
        Manager m1 = new Manager();

        // Derived class property.
        m1.Name = "John";

        // Base class property.
        ((Employee)m1).Name = "Mary";

        System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);
        System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
    }
}

Name in the derived class is: John, Manager

Name in the base class is: Mary

The following are important points 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 (Employee) is used to access the hidden property in the base class:

    ((Employee)m1).Name = "Mary";
    
    

    For more information on hiding members, see the new Modifier (C# Reference).

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.

abstract class Shape
{
    public abstract double Area
    {
        get;
        set;
    }
}

class Square : Shape
{
    public double side;

    public Square(double s)  //constructor
    {
        side = s;
    }

    public override double Area
    {
        get
        {
            return side * side;
        }
        set
        {
            side = System.Math.Sqrt(value);
        }
    }
}

class Cube : Shape
{
    public double side;

    public Cube(double s)
    {
        side = s;
    }

    public override double Area
    {
        get
        {
            return 6 * side * side;
        }
        set
        {
            side = System.Math.Sqrt(value / 6);
        }
    }
}

class TestShapes
{
    static void Main()
    {
        // Input the side:
        System.Console.Write("Enter the side: ");
        double side = double.Parse(System.Console.ReadLine());

        // Compute the areas:
        Square s = new Square(side);
        Cube c = new Cube(side);

        // Display the results:
        System.Console.WriteLine("Area of the square = {0:F2}", s.Area);
        System.Console.WriteLine("Area of the cube = {0:F2}", c.Area);
        System.Console.WriteLine();

        // Input the area:
        System.Console.Write("Enter the area: ");
        double area = double.Parse(System.Console.ReadLine());

        // Compute the sides:
        s.Area = area;
        c.Area = area;

        // Display the results:
        System.Console.WriteLine("Side of the square = {0:F2}", s.side);
        System.Console.WriteLine("Side of the cube = {0:F2}", c.side);
    }
}

Input

 
4
24

Enter the side: 4

Area of the square = 16.00

Area of the cube = 96.00

Enter the area: 24

Side of the square = 4.90

Side of the cube = 2.00

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Not meant to be overloaded
Properties are not meant to be overloaded, there are no parameters to pass in as arguments. A property is meant to be a simple wrapper around a field that represents a piece of logical data.  Properties shouldn't contain any complex or time-sensitive operations. This rules out the overloaded properties concept because if a piece of logical data has ten different ways it can be set, that isn't simple, and your probably clumping together things that should be separated out.  Essentially properties are syntactic sugar that gets translated to a get and set method in the IL code. In general, properties just keep the get and set in one place and are easier to use. Reflection also distinguishes between fields, properties, and methods.  Properties are more a conceptional distinction rather then a functional one.  Don't get hung up on the decision on whether properties are a "good idea" though because any professional .NET developer knows they are used extensively in the C# compiler and .NET library, there is no way around them and that's that. Well, unless you're writing your own C# compiler, .NET library, and don't care about the C# specifications document... in which you would just choose a different programming language. Just want to add that I've been working with .NET and therefore properties for a few years now, and have never ever had a need to overload properties.
give us a overloadable setter
how is this superior to useing even the variable itself as public ??? seriously you cant overload the setter ?

its so pointless to have a setter that cant be overloaded
its like coming up with a great new idea and then forgeting what it was
just before you write a paper on it  
but you go ahead and write the paper telling everyone
its a great new idea the setter but i forgot why ?
umm its just like a get and set method but somehow different
oh wait i know it has less functionallity (scratches head)

oh wait i figured out what you forgot
because overloading the setters allows you to place all your overload sets
in one place
and
keep the getter for them all uniformed to deliver the desired behavior for the overloaded
method that way you dont have multiple method set methods or overloads and multiple gets with similar names
increase the chances for buggs   

alas we forgot to make the setter overloaded oopps
thanks for the carrot on the string
Advertisement