Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy<T> why does it get Func<T>

Can someone please explain in simple words, why does Lazy in C# needs to get Func?

public Lazy (Func<T> valueFactory);

I understand that sometime you need a function in order to do some fancy init().
however, many times I find myself writing a singleton, or something simple, where just create a new instance of the class. As shown in Jon's Skeet book. http://csharpindepth.com/Articles/General/Singleton.aspx

I find this syntax to be very annoying.

Thanks!

private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());
like image 256
Gilad Avatar asked Oct 12 '25 20:10

Gilad


2 Answers

You need a func, because if you could do this:

var Lazy<Foo> = new Lazy<Foo>(new Foo());

You're already instantiating the Foo, which you don't want, otherwise you didn't have to use Lazy<T> to begin with.

The Func<T> holds the initializer for Foo, but only initializes it when you access the Lazy<T>'s Value.

like image 68
CodeCaster Avatar answered Oct 14 '25 09:10

CodeCaster


You can't get the Lazy to work without the initializer function. That is how it ensures the logic for the creation of the object is there, but not yet called.

Consider this:

new Lazy<Singleton>(new Singleton());

This already instantiates a new Singleton. There is no use for the lazy any more. The function allows Lazy<T> to construct the object at any time in the future.

Another plus for the Func<T> is that it doesn't need to be a new object it instantiates. It can be anything else. It can be a multi-line statement, a fetch of something else, etc.

One optimization I could argue for is that new Lazy<T>() would use the new() on T, which prevents the need for you to call the constructor. That is however not possible with the current syntax, but it works with a static factory method.

Something like this (and yes, it is basically does what you do now, but then tucked away in the core):

public static class LazyDefault
{
    public static Lazy<TNew> New<TNew>() where TNew : new()
    {
        return new Lazy<TNew>(() => new TNew());
    }
}

Or as CodeCaster suggested with a derived class:

public class SuperLazy<T> : Lazy<T>
    where T : new()
{
    public SuperLazy()
         : base(() => new T())
    {
    }
}
like image 34
Patrick Hofman Avatar answered Oct 14 '25 10:10

Patrick Hofman