C# Parameterless Properties – An Example
Few weeks ago we investigated how C# Properties are emitted by IL. We saw how the value implicit parameter is introduced and used. In this article we take a look how one can leverage Properties’ potential to build more robust code. The code is self-explanatory and comments are added to indicate not so obvious code.
In this article we also introduce the concept of lazy instantiation. Lazy instantiation is used to delay the creation of an object. The reason for this is that it will speed up the hosting class loading time and objects are only created when they are needed. Lazy instantiation is normally used with objects that take long to initialise or have dependency on modules that might not be available from the start.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PropertiesExample
{
/// <summary>
/// Person is a class to demonstrate the use of Properties in C#
/// </summary>
class Person
{
#region member variables
private string name;
private string surname;
private long id; // auto number - unique person id
private int age;
private DateTime dob; // date of birth
private List<string> achievments; // holds a list of achievements
#endregion
#region properties
/// <summary>
/// FullName is a public readonly property used to combine the person's name
/// with the surname.
/// </summary>
public string FullName
{
get { return string.Format("{0} {1}", this.name, this.surname); }
}
/// <summary>
/// Gets or sets the Date Of Birth.
/// </summary>
public DateTime DateOfBirth
{
get
{
return this.dob;
}
set
{
this.dob = value;
this.age = -1; // reset the age value so that it will be re-calculated when needed
}
}
/// <summary>
/// A readonly property that returns the age of the Person.
/// It uses the concept of Lazy Computation to compute the age of the person.
/// </summary>
public int Age
{
get
{
// Lazy Computation of Age
// Calculate age if only its value is -1
if (this.age == -1)
{
// calculate age
int _age;
DateTime now = DateTime.Today;
_age = now.Year - this.dob.Year;
if (this.dob > now.AddYears(-_age))
_age--;
this.age = _age;
}
return this.age;
}
}
/// <summary>
/// A private property used to Lazy Initialise the list of achievements.
/// This list may not be used so there is no need to initialise it at
/// construction time. If the construction of this achievements list
/// is complex and expensive, then it will not affect the instatiation time
/// of the hosting object, i.e. Person. In this case the instatiation of
/// the List is very light but it is used here to show the pattern and use
/// of Lazy Instantiation.
/// </summary>
private List<string> Achievements
{
get
{
if (this.achievments == null)
this.achievments = new List<string>();
return this.achievments;
}
set
{
this.achievments = value;
}
}
#endregion
#region constructor
public Person(string name, string surname)
{
this.Init(name, surname, DateTime.MinValue); // set Date Of Birth to some value
}
public Person(string name, string surname, DateTime dateOfBirth)
{
this.Init(name, surname, dateOfBirth);
}
private void Init(string name, string surname, DateTime dateOfBirth)
{
this.age = -1; // initialise age to -1 to indicate that it is not computed yet
this.id = DateTime.Now.Ticks;
this.name = name;
this.surname = surname;
this.dob = dateOfBirth;
}
#endregion
#region public methods
public override string ToString()
{
// returns the String representation of this object. It is composed of
// the person's unique id and the full name. Note that here the public
// property is used to return part of the return string.
return string.Format("Person: {0} - {1}", this.id.ToString(), this.FullName);
}
public void AddAchievement(string title)
{
this.Achievements.Add(title);
}
public void PrintAchievements()
{
Console.WriteLine("Achievements:");
foreach (string title in this.Achievements)
{
Console.WriteLine(" {0}", title);
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PropertiesExample
{
class Program
{
static void Main(string[] args)
{
Person person1 = new Person("Black", "White");
Console.WriteLine(person1.ToString());
Console.WriteLine(person1.Age);
person1.DateOfBirth = new DateTime(1975, 12, 25);
Console.WriteLine(person1.Age);
Person person2 = new Person("Red", "Blue", new DateTime(1975, 1, 9));
Console.WriteLine("{0} has {1} years.", person2.ToString(), person2.Age);
Console.WriteLine("Press ENTER to finish");
Console.ReadLine();
}
}
}
Articles
- C# Parameterless Properties – (Part 1)
- C# Parameterless Properties – (Part 2)