Performance has always been overhead for all programmers. They try to optimize code using various techniques. Like Lazy Loading, Lazy instantiating is also a great candidate, and with .NET 4.0 implementation of Lazy<T>.
Being lazy is not encouraged and everyone is expected to become proactive but the programming world behaves differently. Here, we love to get something only when it is needed.
What is this?
This is the .NET framework implementation of lazy instantiation. That means instantiating an object only when it is needed. For this, we normally use large objects or resource extensive objects.
This is thread-safe for creation; i.e. when an object is instantiated in a multithreaded setup, using Lazy<T> will ensure only ONE single instance of the object and it is created by one thread ONLY.
Please make sure, that only object creation is thread-safe, if you need to use this object from different threads, it will need locking to avoid a race condition.
Use Case
When it is very expensive to create an object or we know in advance that dependent objects will NOT be needed all the time, we can use this.
Scenario # 1
For my Insurance, I enter my insurance ID, but at this point, I may navigate to renew, cancel, file a claim, etc. so in this condition I may not need to load my complete insurance history unless I ask for it.
Scenario # 2
Using Singleton class. I will explain this code in the next section of this article and where we will know more about this.
How to use it?
Lazy<T> comes with many constructors and more options but will restrict this article to the most common scenario.
- Lazy < LargeObject > lazyLargeObject = new Lazy < LargeObject > (GetInsuranceHistory);
- static LargeObject GetInsuranceHistory() {
-
- return large;
- }
Another way of instantiating using delegates,
- Lazy < LargeObject > lazyLargeObject = new Lazy < LargeObject > (() => {
-
- return large;
- });
One real-life Scenario and Code Explanation
As promised, here is a singleton class example and in the following section, I am going to explain
Scenario
In this code, I want to cache some master data and I will be instantiating them only when it is needed for the first time and once, they are instantiated, it shall not make any operation to instantiate again. To insert a delay in the process to imitate the long process.
Code Flow
With the lazy instantiation of the class, we are passing GetData method as a parameter. GetData method fetches records from the database/calculating value and assigns values to the local private variables.
- public sealed class DataCache {
- private static Lazy < DataCache > local = new Lazy < DataCache > (GetData);
- private List < string > _names = null;
- public static List < string > Names {
- get {
- return local.Value._names;
- }
- }
- private static DataCache GetData() {
- DataCache cache = new DataCache();
- cache._names = Employees.GetNames();
- Console.WriteLine("GetData Method Called");
- return cache;
- }
- }
- public class Employees {
- public static List < string > GetNames() {
- System.Threading.Thread.Sleep(2000);
- return new List < string > () {
- "Atul",
- "Ramesh",
- "Mahesh",
- "Devesh",
- "Ajay"
- };
- }
- }
Lazy is instantiated when Value is called, and in this case, Value is called from the static property.
Now, to access the value of cache values, we need to call the property from an external client.
Ensure only One instance is created
For that, in GetData I will print the message. In the client application, I will call this 10 times but as output, we will see only ONE message printed in the console.
- static void Main(string[] args) {
- for (int i = 0; i < 10; i++) {
- var x = DataCache.Names;
- }
-
- Console.ReadLine();
- }
I hope this example gives you a fair idea of Lazy<T> and code is
available here to play around.