Friday, September 3, 2010

Lazy initialization – Lazy (.NET 4.0)

With lazy initialization, the memory for an object is not allocated until it is needed. This mainly used to improve performance, reduces unnecessary computations and also reduce memory requirements. This can be useful in following scenarios:

  1. When creation of object is expensive and we want to deferred the creation until it is used.
  2. When you have an object that is expensive to create, and the program might not use it. For example, assume that you have in memory a Customer object that has an Orders property that contains a large array of Order objects that, to be initialized, requires a database connection. If the user never asks to display the Orders or use the data in a computation, then there is no reason to use system memory or computing cycles to create it. By using Lazy<Orders> to declare the Orders object for lazy initialization, you can avoid wasting system resources when the object is not used.
Example:



class MyClass
{
    public string MyData { get; set; }

    public MyClass(string message)
    {
        this.MyData = message;
        Console.WriteLine("  ***  MyClass constructed [{0}]", message);
    }
}



We can declare and use this by creating a lambda expression to pass in our string parameter:
Lazy<MyClass> classInstance = new Lazy<MyClass>(
        () => new MyClass("The message")
    );
We then have access to the IsValueCreated property, which tells us whether or not the instance has been created, as well as the Value property, which will construct and return our actual instance on demand.
Here’s an example showing a complete program using the MyClass above, demonstrating the usage of Lazy<T>:
class Program
{
    static void Main(string[] args)
    {        
        MyClass instance1 = new MyClass("instance1");
        Lazy<MyClass> instance2 = new Lazy<MyClass>(() => new MyClass("instance2"));
        Console.WriteLine("Instances declared");
        Console.WriteLine();
        Console.WriteLine("instance2's MyClass initialized:  {0}", instance2.IsValueCreated);
        Console.WriteLine(); 

        Console.WriteLine("instance1.MyData: {0}", instance1.MyData);
        Console.WriteLine("instance2.MyData: {0}", instance2.Value.MyData);
        Console.WriteLine();
        Console.WriteLine("instance2's MyClass initialized:  {0}", instance2.IsValueCreated);
        Console.ReadKey();
    }
}
The above program, when run, prints out:
***  MyClass constructed [instance1]
Instances declared

instance2's MyClass initialized:  False

instance1.MyData: instance1
  ***  MyClass constructed [instance2]
instance2.MyData: instance2

instance2's MyClass initialized:  True
So, this LAZY type automatically delayed our construction until the first type we accessed it (instance2.Value.MyData).

No comments:

Post a Comment