Support Forums

Full Version: [C#] Lazy Initialization Test (Lazy<T>)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Here's a test snippet that I created to demonstrate a phenomena called "Lazy initialization".

Code:
private void MainMethod()
{
    Lazy<MyClass> mClass = LazyClass1; /* Choose LazyClass1 or LazyClass2 */

    Console.WriteLine();
    Console.WriteLine("[#] Value Created: {0}", mClass.IsValueCreated);
    Console.WriteLine("[#] Name: {0} [ID - {1}]", mClass.Value.Name, mClass.Value.ID);
    Console.WriteLine("[#] Value Created: {0}", mClass.IsValueCreated);
}

#region Lazy<T> Code

Lazy<MyClass> LazyClass1 = new Lazy<MyClass>(() => { return new MyClass() {
    ID = 1,
    Name = "AceInfinity"
}; });
Lazy<MyClass> LazyClass2 = new Lazy<MyClass>(() => { return new MyClass(); });

public class MyClass
{
    public int ID { get; set; }
    public string Name { get; set; }

    public MyClass() : this(0, "{Default}") { }

    public MyClass(int vID, string vName)
    {
        Console.WriteLine("[!] Constructor called for initialization...");

        ID = vID;
        Name = vName;
    }
}

#endregion

What's the point? If you run through my code above you'll see that only after the constructor is called that a Value is created for the Lazy<T>. What's the significance? It means that the constructor is only called for initialization when we try to use a value. We may consider this useful because now this enables us to save memory for the initialization through the constructor for this class until we actually need to use a value from the initialized class itself.

Great for optimization and performance reasons...

I give you 2 constructor overloads to play around with, and they can be called by either using LazyClass1 or LazyClass2 Lazy<MyClass> to define the mClass Lazy<MyClass>, but the default one is modified and chained to the other master constructor with 2 params so that I didn't have to write out the Console.Writeline() line in both constructors.

http://msdn.microsoft.com/en-us/library/dd997286.aspx
http://msdn.microsoft.com/en-us/library/dd642331.aspx
Note: The reason for this:
Code:
new Lazy<MyClass>(() => { return new MyClass(); });

What we're doing here is using the optional param which expects a generic delegate of type System.Func<>, which is why you see a lambda expression, and what we are doing here is pointing to a method (through the lambda), which returns the same type created by the Lazy<T>; the MyClass object. Remember that when you create a class, what you're really doing is creating an object, because classes are derived from System.Object as with every other type either directly or indirectly.

Here's the problem, when we create the Lazy<T> variable, we're invoking the default constructor for MyClass, so the trick i've done here is chained that default constructor to a 'master constructor' which accepts 2 params, of type int, and string. Smile

With 4.0 this generic class essentially just allows you to allocate memory hogging objects only at the time you require them.
Great share!

I am a man of Framework myself, hope to see more from you soon!
(08-05-2012, 06:35 PM)Cubs Wrote: [ -> ]Great share!

I am a man of Framework myself, hope to see more from you soon!

Hopefully this example shows people the usefulness of the Lazy<T> generic class. Smile