• (3 Pages)
  • +
  • 1
  • 2
  • 3

C# Learning Series - Properties

#1 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5628
  • View blog
  • Posts: 12,071
  • Joined: 02-June 10

Posted 10 November 2012 - 05:08 PM

*
POPULAR

Learning C# Series

Properties




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?
The professional coding community uses properties extensively. Its a primary concept. Its how classes communicate with each other. If your code doesn't use them then its going to be a real headache to interact with other classes. Making your code not follow established styles and technology is going to hinder you and make your code something that no co-worker or employer will want to deal with.



Terms you should be familiar with:
Spoiler





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




Properties can best be thought of as advanced variables. You call and use them like variable. From the caller's point of view
public string Name;

and
public string Name { get; set; }

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

    }
}

Posted Image

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.

Posted Image




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.

Posted Image


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:
Spoiler




Is This A Good Question/Topic? 32
  • +

Replies To: C# Learning Series - Properties

#2 danzar  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 8
  • View blog
  • Posts: 108
  • Joined: 10-December 08

Posted 11 November 2012 - 11:23 AM

Very Nice Tut, Thank you.
Was This Post Helpful? 0
  • +
  • -

#3 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5628
  • View blog
  • Posts: 12,071
  • Joined: 02-June 10

Posted 11 November 2012 - 12:06 PM

Hope it helps. Your mileage may vary. Close cover before striking. Don't tug on Superman's cape.
Was This Post Helpful? 0
  • +
  • -

#4 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1253
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Posted 12 November 2012 - 06:05 AM

Wonderful job with these tutorials, I'm sure they'll be a massive help to people who are starting out.
Was This Post Helpful? 0
  • +
  • -

#5 danzar  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 8
  • View blog
  • Posts: 108
  • Joined: 10-December 08

Posted 12 November 2012 - 06:49 AM

Well I also think these tut's are great for the seasoned programmer also. A new prospective on something is nothing but a great thing.
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5628
  • View blog
  • Posts: 12,071
  • Joined: 02-June 10

Posted 07 December 2012 - 02:37 PM

07dec12 - This tutorial has been read nearly 4,000 times but only 8 people ticked it as a good topic.

Is it really that bad? Is it hard to understand? Did I not cover material you, the reader, really need or want? I can't improve the quality of my tutorial writing style without feedback from you.

Thanks!
Was This Post Helpful? 2
  • +
  • -

#7 ScottinTexas  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 13-March 12

Posted 15 December 2012 - 05:15 AM

As for me I like tuts like this because it helps me clean up my thinking and gives me the syntax I need for putting a new language to use. I use classes and properties in VBA all the time, but there is nothing to compare with INotifyPropertyChanged. That's what I needed. I knew what a property was but read through this tutorial anyway. Glad I did.
Was This Post Helpful? 0
  • +
  • -

#8 maj3091  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 303
  • View blog
  • Posts: 1,793
  • Joined: 26-March 09

Posted 18 January 2013 - 02:12 PM

I'm finding all these tutorials really useful, as I'm slowly dragging myself into the world of OOP and .Net from VB6.

Thanks.
Was This Post Helpful? 0
  • +
  • -

#9 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5628
  • View blog
  • Posts: 12,071
  • Joined: 02-June 10

Posted 18 January 2013 - 02:22 PM

Thanks for the kind words. That's what keeps us motivated to make more when we have spare time.
Was This Post Helpful? 1
  • +
  • -

#10 h4nnib4l  Icon User is offline

  • The Noid
  • member icon

Reputation: 1182
  • View blog
  • Posts: 1,677
  • Joined: 24-August 11

Posted 21 January 2013 - 10:21 AM

Looks like my last comment disappeared into the ethers...

Great tutorial. Every one of your tutorials that I've read has been useful to me, even ones over basic topics like this, because I always learn something. Thank you for all of your work on these; I'm reasonably certain that a majority of the problems posted in the various .NET forums would never be posted if users were forced to read all of the links in your various sigs before they were allowed to post. I know your stuff has helped me numerous times.
Was This Post Helpful? 0
  • +
  • -

#11 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5628
  • View blog
  • Posts: 12,071
  • Joined: 02-June 10

Posted 21 January 2013 - 10:49 AM

Thanks. I appreciate it.
Was This Post Helpful? 0
  • +
  • -

#12 JimPickens  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 05-February 13

Posted 05 February 2013 - 12:27 PM

Very good. Thanks for your effort.
Was This Post Helpful? 0
  • +
  • -

#13 acProgrammer  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 20
  • Joined: 23-March 13

Posted 07 April 2013 - 03:58 PM

Iam reading this one because you suggested as a reply to my inquiring on the get;set which I am not familiar with...the first example is


public class TextArgs : EventArgs  




Already I am intimidated and wondering what!?!

I get it is a public class - that you have an argument & an eventhandler to handle the argument ... but this is a bit of a mystery to me still.

Interestingly - I am taking a college course - I am able to throw basic programs together pretty quick - or at least I am getting quicker - but I am being taught how to code behind the object. Am I just trying to figure too much out too quickly. You seem to think this is basic so I can't help but wonder why I feel I am getting it in class but in the 'read world' I feel as if I am not getting it at all.

Encouraging feedback would be appreciated as I am wondering what in the world have I gotten myself into here.
Was This Post Helpful? 1
  • +
  • -

#14 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2270
  • View blog
  • Posts: 9,496
  • Joined: 29-May 08

Posted 07 April 2013 - 04:06 PM

public class TextArgs : EventArgs 



Is defining a class called TextArgs that is a subtype (or inherits from) the class EventArgs which is the basetype.

In vb.net it is the following.
Public Class TextArgs
 Inherits EventArgs


Was This Post Helpful? 2
  • +
  • -

#15 acProgrammer  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 20
  • Joined: 23-March 13

Posted 07 April 2013 - 04:17 PM

View PostAdamSpeight2008, on 07 April 2013 - 04:06 PM, said:

public class TextArgs : EventArgs 



Is defining a class called TextArgs that is a subtype (or inherits from) the class EventArgs which is the basetype.

In vb.net it is the following.
Public Class TextArgs
 Inherits EventArgs



Above was helpful & makes sense - but the example given was:

public class TextArgs : EventArgs  

02 {  
03     #region Fields  
04     private string szMessage;  
05     #endregion Fields  
06  
07     #region ConstructorsH  
08     public TextArgs(string TextMessage)  
09     {  
10         szMessage = TextMessage;  
11     }  
12     #endregion Constructors  
13   
14     #region Properties  
15     public string Message  
16     {  
17         get { return szMessage; }  
18         set { szMessage = value; }  
19     }  
20     #endregion Properties  
21 } 



So - I am still confused cuz I don't even see the event anywhere else - how would the code that referenced this event look & what is the purpose of this code?

This post has been edited by tlhIn`toq: 07 April 2013 - 04:44 PM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3