Posted on January 31 2011 by Joseph D'Emanuele

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

Be Sociable, Share!