Properties are a central concept in .NET languages and a foundation principal when building classes. They have several advanced features over simple field variables and their use is integrated in many way throughout class interaction. Understanding how to properties work, and more importantly how properties can make your application smarter friendlier and easier to code is vital to advancing your trade-craft as a software developer.
Why is this important to learn about?
Terms you should be familiar with:
Note: All examples were created using Visual Studio 2012, targetting the .NET Framework 4.5, using a WPF project. We'll do our best to point out anything that might not work in older versions or ways of using the same techniques in WinForms.
Properties can best be thought of as advanced variables. You call and use them like variable. From the caller's point of view
and
are exactly the same thing. "So why do I care about properties?" is probably your first through. Because as mentioned they are an advanced construct. In reality they are a wrapper around a get and set method. Let me say that again: Properties are a wrapper around two methods. And as we know methods are exectuable code that can do things and make comparrisons and decisions. Simple variables can't do anything.
In its simplest syntax a property can be autoset, meaning it has no backing field variable (more on this in a sec., so don't panic) The Name property above is an autoset property. It has a get and a set method that contain nothing. It will act exactly like any other variable. But that's like using a Ferrari to get groceries: Its under utilizing the tools at your disposal.
The get method within the property uses an important keyword: value
That is the value being passed in. You can work with that value within the get method. The only condition on this is that as soon as you start doing these things you have to have a backing variable for the property. The value has to be stored someplace while the methods do their job. Let's see it in action so it becomes clear.
private int _Age = 0;
public int Age
{
get { return _Age; }
set
{
if (value < 0) value = 0;
_Age = value;
}
}
In our example Age is the property, _Age is the backing variariable.1
If you had a simple int variable for someone's age your code would have to validate it everyplace you used it. A typical program might refer to the Age 100 times. What if somewhere in all that our calculation screwed up? Do we really want to have to qualify every calculation every time? Worse yet, what if there are new rules put into place about validating age: We would have to scrub through thousands of lines of code and copy/paste the new rules into the 100 places we do it. YUCK!
For example, what if the age was accidentally set to a negative number? Its legal for an int to be -4, but that's not a valid age. But the get method executes on incoming values. We can make an age property that does this for us one time, in one place so we don't have to validate the age in 100 places.
void SomeMethod()
{
// Do a bunch of fancy stuff and get information from a database
// In the course of our work we update the Age property.
Age = OurNewCalculatedValue;
}
Let's assume that after a faulty calculation OurNewCalculatedValue is -18 instead of positive 18. Well -18 is certainly not a valid age. Let's walk through how our property will validate and overcome wrote values being passed in:
Age = OurNewCalculatedValue; // is therefore
Age = -18; // Sending -18 as the value to the set method within the Age property.
set
{
if (value < 0) // {which is} if (-18 < 0) so yeah, this is true
value = 0; // set the value to 0
_Age = value; // set our backing field variable to our corrected value
}
}
What happens most of the time when the original calculation doesn't screw up? Let's assume that after a correct calculation OurNewCalculatedValue is positive 21: A perfectly valid age
set
{
if (value < 0) // {which is} if (21 < 0) nope, not the case
value = 0; // so this line doesn't execut
_Age = value; // set our backing value to the passed in value of 21
}
}
So if only for the capability of centralizing the validation of values properties are well worth the time. But wait! There's more! And this one is a doozy. There is an interface called INotifyPropertyChanged. We love this! The short description is: This how a property can raise an event telling any subscriber that it's value has been changed. Picture this very common situation:
You have a window and on it are various controls with information about a persion: Name, age, address, phone number etc. When a user inputs a change you want the property to update. By the same token if the age updates from an programmatic source (like a database update) you want the GUI to update automatically. This is exactly the same as say a calculator. When the math is done the Answer property is updated and you want that to be shown on screen. Or you are writting a chat program and the Message property updates when a new message is received.... Or you are watching a USB weather station and the Temperature gets a new value so you want that on-screen.
This is pretty much how any program should work: The work class does the work and the GUI acts as an interface between the user and the work.
You could do this:
private int _Age = 0;
public int Age
{
get { return _Age; }
set
{
if (value < 0) value = 0;
_Age = value;
lbl_Age.Text = value;
}
}
//and
void lbl_Age_TextChanged(object sender, eventargs e)
{
Age = Convert.ToInt32(lbl_Age.Text);
}
But that violates a prime rule of OOP: One clase shouldn't know more than is necessary about another class. AND your data shouldn't be tightly bound to your GUI. The problem here becomes if a designer changes the layout or names of the controls on the GUI then the data class breaks because it is calling those controls directly. And the controls would have to be made public making them vulnerable to unintentional changes... and... and... and...
So instead we want to just raise up a notice (an event) that the data has been updated. The data class doesn't know or care who's listening: That's the responsiblity of the listener to update itself. Not the responsibility of a pure data class to fix up the GUI.
All we have to do is bind the value of the GUI control to the property, then tell the property to raise a PropertyChanged event when it gets set
WPF example:
In the C# code behind we
- Line 9: add a using statement for System.ComponentModel because that's where interface INotifyPropertyChanged lives.
- line 16: Add INotifyPropertyChanged to our class signature
- Lines 40-48: Impliment the events for INotifyPropertyChanged
That stuff is just one time, to get our class prepped. You don't do that for every property. - Line 33: When the property gets changed, raise an event saying so.
// Using statements tell our assembly where to look for commands.
// They let us abreviate our code a little.
// For example bool is really System.Bool but nobody want to type
// System.Bool each and every time you use it. So we place a
// using System statement at the hed of the file. When the compiler
// sees 'bool' it will start looking through all of our usings to
// find where this object is defined.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace DicTutorial
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
// Constructor method (Note lack of return type and name matches the name of the class)
public MainWindow()
{
InitializeComponent();
}
#region Property Tutorial
private int _Age = 0;
public int Age
{
get { return _Age; }
set
{
if (value < 0) value = 0;
_Age = value;
RaisePropertyChanged("Age");
}
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, e: new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}

Then on our WPF window we bind the .Value of the control to the Age property, speicfying two way. That way when the property is changed the GUI is updated, and when the GUI is changed the property is updated.

Now that all the groundwork has been laid we can add as many easy-to-bind properties as we like. For a contact card we might add Name, address and so on to our existing Age property. One of my most common uses is to give the user status updates on the status bar at the bottom of the window.

Add all we had to do was add one more property that that reports when it has a change.
private string _Status;
public string Status
{
get { return _Status; }
set
{
if (_Status == value) return;
_Status = value;
RaisePropertyChanged("Status");
}
}
Now we can give the user status updates easily with a single line from any method in our application.
bool DownloadData()
{
// Fancy download code
Status = "Download complete";
return true;
}
void ReceiveNewTemperatureFromWeatherStation(int NewTemp)
{
WriteNewTempToDatabase(NewTemp);
Status = string.Format("New Temp: {0}f", NewTemp);
}
void ExitApplication()
{
Status = "Cleaning up before close";
SaveUnsavedData();
}
In Conclusion
There is even more advanced features about properties. But this tutorial is already getting pretty long. We've covered the basics about what properties are and even some intermediate stuff about cool ways to use them. Hopefully this will get you thinking, and using properties as much as possible.
See all the C# Learning Series tutorials here!
Footnotes
1Naming convention:






MultiQuote







|