TOC

The community is working on translating this tutorial into Slovak, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".

Classes:

Properties

In the previous article, we discussed fields. They are like global variables for a class, allowing you to access them from all methods. We also briefly discussed the fact that fields CAN be accessed from other classes if they are marked as public, but that this is generally not recommended. For variables/fields that you wish to access from outside your class, you should instead use properties.

When you declare a field as public, you are giving complete access to it from the outside - other classes can do whatever they want with it, without any notice to the declaring class. Properties gives the control back to the declaring class, by specifying whether a field is read or write-only and even allowing the declaring class to check and manipulate the value before returning or assigning it to the field.

A property looks a bit like a crossover between a field and a method, because it's declared much like a field with visibility, a data type and a name, but it also has a body, like a method, for controlling the behavior:

public string Name
{
	get { return _name; }
	set { _name = value; }
}

Notice the special get and set keywords. They are used exclusively for properties, to control the behavior when reading (get'ing) and writing (set'ing) the field. You can have properties with only a get OR a set implementation, to create read-only or write-only properties, and you can even control the visibility of the get or set implementations, e.g. to create a property which can be read from anywhere (public) but only modified from inside the declaring class (private).

You will also notice that I refer to a field called _name. You will have to declare that in your class as well, so that your property can use it. A common usage pattern for fields and properties will look like this:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
	set { _name = value; }
}

You can now see how the field and the property works together: The get method will return the value of the _name field, while the set method will assign the passed value to the _name field. In the set method, we use the special keyword value which, in this specific situation, will refer to the value passed to the property.

So, this is pretty much as basic as it gets and at this point, we don't do anything that couldn't be accomplished with a simple public field. But at a later point, you may decide that you want to take more control of how other classes can work with the name and since you have implemented this as a property, you are free to modify the implementation without disturbing anyone using your class. For instance, the Name property could be modified to look like this:

private string _name = "John Doe";

public string Name
{
	get 
	{
		return _name.ToUpper();
	}
	set 
	{
		if(!value.Contains(" "))
			throw new Exception("Please specify both first and last name!");
		_name = value; 
	}
}

The get method now enforces that the value returned is always in UPPERCASE, no matter which case the backing field (_name) is in. In the set method, we have added a couple of lines of code to check whether the passed value contains a space, because we have decided that the name should always consist of both a first and a last name - if this is not the case, an exception is thrown. This is all very crude and simplified, but it should illustrate the full level of control you get when using properties.

Auto-implemented properties

In some cases, you don't need all the control over a field and it can feel cumbersome to implement both a field and a property with the get and set methods not doing anything besides what we saw in the first example. You may be tempted to simply declare your variable as a public field to avoid all this extra hassle. But don't do that! Fortunately for all of us, Microsoft decided to add auto-implemented properties in C# version 3, which will save you several lines of code. Just consider the difference:

Regular property with a declared backing field:

private string _name;

public string Name
{
	get { return _name; }
	set { _name = value; }
}

The exact same behavior, but with an auto-implemented property:

public string Name { get; set; }

Notice that the get and set methods are empty and that no private backing field is declared - in other words, we can now accomplish the exact same behavior as in the first example but with a single line of code! Bear in mind that the private backing field will still exist at runtime - it will be auto-implemented by the compiler, as the name implies. Should you later decide that you need more control of this specific property, you can simply change it to a regular field/property combination with the desired implementation of the get and set methods.

Notice that you are still left with an important mechanism of control from regular properties when using auto-implemented properties: You can leave out the set keyword to create a read-only property, e.g. like this:

public string ReadOnlyProperty { get; }

Write-only properties are not allowed when using auto-implemented properties.

Auto-implemented properties with default values

Prior to C# version 6, you could not define a default value for an auto-implemented property - for that, you would need a declared backing field, which would allow you to initialize the variable with a value:

private string _name = "John Doe";

public string Name
{
	get { return _name; }
	set { _name = value; }
}

But in C# version 6, Microsoft finally added the ability to initialize an auto-implemented property with a default value, like this:

public string Name { get; set; } = "John Doe";

Summary

Properties gives your classes more control over how fields can be accessed and manipulated, and they should always be used when you want to give access to fields from outside of the declaring class.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!