Microsoft .Net framework 4.0 or later version provides a concept called Lazy initialization.
Using this concept we can increase the performance while loading time or startup time. To know, where we can implement this concept, just check the below scenario-
Suppose in our application, there are some objects which contain other child objects
and to fill those child object we have some logic or computation which takes
time. But at the time of application startup, we want only parent class properties;
in this case if we will create the object of parent class then it will take time
because some part of the time will be consumed to fill the child object.
To avoid this condition, we can implement the concept called Lazy initialization
using Lazy<T> of .Net, which will increase the performance. Here âTâ is the type of object that
is being lazily initialized.
Code Implementation-
To explore this, I have created two classes- Parent and Child, to maintain parent
-child relationship, I have defined 2 properties (LstChild and LstChildLazy)
in parent class as child type. Here I am filling dummy data to LstChild without
Lazy Class and LstChildLazy with Lazy class.
//Parent Class
public class ParentClass
{
public int intParentID{get;set;}
public string strParentName{get;set;}
//Filling child class object without Lazy class
private List<Child> _lstChild;
public List<Child> LstChild
{
get
{
if (_lstChild == null)
{
_lstChild = new List<Child>();
for (int i = 0; i < 1000000; i++)
{
_lstChild.Add(new Child() { intChildID = i, strChildName = "Name" + i.ToString() });
}
}
return _lstChild;
}
set
{
_lstChild = value;
}
}
//Filling child class object with Lazy class
private List<Lazy<Child>> _lstChildLazy;
public List<Lazy<Child>> LstChildLazy
{
get
{
if (_lstChildLazy == null)
{
_lstChildLazy = new List<Lazy<Child>>();
for (int i = 0; i < 1000000; i++)
{
_lstChildLazy.Add(new Lazy<Child>(() => new Child { intChildID = i, strChildName = "Name" + i.ToString() }));
}
}
return _lstChildLazy;
}
set
{
_lstChildLazy = value;
}
}
}
//Child Class
public class Child
{
public int intChildID { get; set; }
public string strChildName { get; set; }
}
In above code you can see I have same for loop to fill the both properties. Now to
track the loading or startup time I have taken 2 buttons and written different
code. Check below code-
//Processing items without Lazy Class
private void btnProcess_Click(object sender, EventArgs e)
{
try
{
//Stopwatch to track the time
Stopwatch sw = new Stopwatch();
sw.Start();
ParentClass objParentClass = new ParentClass();
objParentClass.intParentID = 1;
objParentClass.strParentName = "Parent1";
//Getting child class object
List<Child> objParentClass_Child= objParentClass.LstChild ;
sw.Stop();
lblWithoutLazy.Text = "ElapsedMilliseconds : " + sw.ElapsedMilliseconds.ToString ();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Processing items with Lazy Class
private void btnProcessWithLazy_Click(object sender, EventArgs e)
{
try
{
//Stopwatch to track the time
Stopwatch sw = new Stopwatch();
sw.Start();
ParentClass objParentClass = new ParentClass();
objParentClass.intParentID = 1;
objParentClass.strParentName = "Parent1";
//Getting child class object with Lazy class
List<Lazy<Child>> objParentClass_Child = objParentClass.LstChildLazy;
sw.Stop();
lblWithLazy.Text = "ElapsedMilliseconds: " + sw.ElapsedMilliseconds.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Description-
btnProcess_Click()- This is implemented without Lazy class object
btnProcessWithLazy _Click()- This is implemented with Lazy class object
Now check the below output-

You can see that Lazy initialization is taking less time compare to normal initialization.
This implementation increase the application startup or loading time because
Lazy initialization occurs the first time the Lazy<T>.Value property is
accessed means Lazy loading is initializing the member the first time it is requested.
The additional advantage of Lazy<T> class is that be default all the members of this class are thread safe so that members can be shared concurrently with multiple thread.
Point of Interest-
It can be easily identified that the value has been created for object or not by
using IsValueCreated property.
Example-
public class clsEmp
{
string strFname;
string strLname;
public clsEmp()
{
strFname = "Jitendra";
strLname = "Faye";
}
public string GetFullName()
{
return strFname + " " + strLname;
}
}
private void button1_Click(object sender, EventArgs e)
{
Lazy<clsEmp> lazyEmp = new Lazy<clsEmp>();
MessageBox.Show("Value created :" + lazyEmp.IsValueCreated); // False
clsEmp objEmp = lazyEmp.Value;
MessageBox.Show("Value created :" + lazyEmp.IsValueCreated); // True
MessageBox.Show("Full Name:" + objEmp.GetFullName());
}
For first call of lazyEmp.IsValueCreated return value will be False because in this time no value will be created for Lazy<T> instance.
But once we call lazyEmp.Value then clsEmp class constructor will be executed and allocation will take place. In
second call of lazyEmp.IsValueCreated return value will be True.
Lazy loading also reduce the consumption of memory because of on-demand memory allocation.
You can download the complete code from here-
Lazy initialization