C# Parameterless Properties – (Part II)

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.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace PropertiesExample
  7. {
  8.     /// <summary>
  9.     /// Person is a class to demonstrate the use of Properties in C#
  10.     /// </summary>
  11.     class Person
  12.     {
  13.         #region member variables
  14.         private string name;
  15.         private string surname;        
  16.         private long id;                     // auto number - unique person id
  17.         private int age;
  18.         private DateTime dob;               // date of birth
  19.         private List<string> achievments;   // holds a list of achievements
  20.         #endregion
  21.  
  22.         #region properties
  23.         /// <summary>
  24.         /// FullName is a public readonly property used to combine the person's name
  25.         /// with the surname.
  26.         /// </summary>
  27.         public string FullName
  28.         {
  29.             get { return string.Format("{0} {1}", this.name, this.surname); }
  30.         }
  31.  
  32.         /// <summary>
  33.         /// Gets or sets the Date Of Birth.
  34.         /// </summary>
  35.         public DateTime DateOfBirth
  36.         {
  37.             get 
  38.             { 
  39.                 return this.dob; 
  40.             }
  41.             set 
  42.             { 
  43.                 this.dob = value;
  44.                 this.age = -1; // reset the age value so that it will be re-calculated when needed
  45.             }
  46.         }
  47.  
  48.         /// <summary>
  49.         /// A readonly property that returns the age of the Person.  
  50.         /// It uses the concept of Lazy Computation to compute the age of the person.
  51.         /// </summary>
  52.         public int Age
  53.         {
  54.             get
  55.             {
  56.  
  57.                 // Lazy Computation of Age
  58.                 // Calculate age if only its value is -1
  59.                 if (this.age == -1)
  60.                 {
  61.                     // calculate age
  62.                     int _age;
  63.                     DateTime now = DateTime.Today;
  64.                     _age = now.Year - this.dob.Year;
  65.                     if (this.dob > now.AddYears(-_age)) 
  66.                         _age--;
  67.  
  68.                     this.age = _age;
  69.                 }
  70.  
  71.                 return this.age;
  72.             }
  73.         }
  74.  
  75.         /// <summary>
  76.         /// A private property used to Lazy Initialise the list of achievements.
  77.         /// This list may not be used so there is no need to initialise it at
  78.         /// construction time.  If the construction of this achievements list
  79.         /// is complex and expensive, then it will not affect the instatiation time
  80.         /// of the hosting object, i.e. Person.  In this case the instatiation of
  81.         /// the List is very light but it is used here to show the pattern and use 
  82.         /// of Lazy Instantiation.
  83.         /// </summary>
  84.         private List<string> Achievements
  85.         {
  86.             get
  87.             {
  88.                 if (this.achievments == null)
  89.                     this.achievments = new List<string>();
  90.  
  91.                 return this.achievments;
  92.             }
  93.             set
  94.             {
  95.                 this.achievments = value;
  96.             }
  97.         }
  98.         #endregion
  99.  
  100.         #region constructor
  101.         public Person(string name, string surname)
  102.         {
  103.             this.Init(name, surname, DateTime.MinValue);  // set Date Of Birth to some value
  104.         }
  105.  
  106.         public Person(string name, string surname, DateTime dateOfBirth)
  107.         {
  108.             this.Init(name, surname, dateOfBirth);
  109.         }
  110.  
  111.         private void Init(string name, string surname, DateTime dateOfBirth)
  112.         {
  113.             this.age = -1; // initialise age to -1 to indicate that it is not computed yet
  114.             this.id = DateTime.Now.Ticks;
  115.  
  116.             this.name = name;
  117.             this.surname = surname;
  118.             this.dob = dateOfBirth;
  119.         }
  120.         #endregion
  121.  
  122.         #region public methods
  123.         public override string ToString()
  124.         {
  125.             // returns the String representation of this object.  It is composed of
  126.             // the person's unique id and the full name.  Note that here the public
  127.             // property is used to return part of the return string.
  128.             return string.Format("Person: {0} - {1}", this.id.ToString(), this.FullName);
  129.         }
  130.  
  131.         public void AddAchievement(string title)
  132.         {
  133.             this.Achievements.Add(title);
  134.         }
  135.  
  136.         public void PrintAchievements()
  137.         {
  138.             Console.WriteLine("Achievements:");
  139.             foreach (string title in this.Achievements)
  140.             {
  141.                 Console.WriteLine(" {0}", title);
  142.             }
  143.         }
  144.         #endregion
  145.     }
  146. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace PropertiesExample
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             Person person1 = new Person("Black", "White");
  13.             Console.WriteLine(person1.ToString());
  14.             Console.WriteLine(person1.Age);
  15.             person1.DateOfBirth = new DateTime(1975, 12, 25);
  16.             Console.WriteLine(person1.Age);
  17.             Person person2 = new Person("Red", "Blue", new DateTime(1975, 1, 9));
  18.             Console.WriteLine("{0} has {1} years.", person2.ToString(), person2.Age);
  19.  
  20.             Console.WriteLine("Press ENTER to finish");
  21.             Console.ReadLine();
  22.         }
  23.     }
  24. }

Articles