-1

I was reading some .NET 4+ code where it use a lambda in Lazy's constructor, like this new Lazy<Foo>(() => new Foo()). How does it differ from new Lazy<Foo>() when no arguments are passed to Foo's constructor?

Jack
  • 16,276
  • 55
  • 159
  • 284

4 Answers4

2

From my understanding you would use the lambda expression form when you want to pass in parameters to use in the initialization. I don't think there's a use case for the lambda without parameters.

Dmitry K.
  • 972
  • 6
  • 16
  • To be nit picky, reflection to create instances of objects is slower than executing a lambda to construct the instance. Of course it might not matter at all, depending on your use case, but someone somewhere will probably have a use case. – Chris Taylor Apr 30 '16 at 02:53
  • I agree but (sort-of)ironically, not 5 minutes ago I just saw this link in a different question and your comment reminded me of it. [Performance Rant](https://ericlippert.com/2012/12/17/performance-rant/) – Dmitry K. Apr 30 '16 at 03:02
2

new Lazy<Foo>() uses reflection to create an instance of Foo calling the default constructor using something like the following code Activator.CreateInstance(typeof(T)). This implies that Foo must have a default constructor.

On the other hand Lazy<Foo>(Func<T>), if required, gives you more flexibility with regard to the construction of the instance created via the Lazy type.

Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
1

The default Lazy constructor is useful when the type can be instantiated with a default constructor. This means new Lazy<Foo>(() => new Foo()), where Foo takes no constructor parameters, can be simplified to new Lazy<Foo>() in most cases.

The exception is when the type's constructor is private — since as mentioned the default Lazy<T> constructor uses Activator.CreateInstance(typeof(T)), this will not work if the constructor is private, even if it takes no parameters. For example, one might implement a singleton using Lazy<T> as follows:

public class Foo
{
    // Notice that the Lazy(Func<T>) constructor is used here
    // because Foo's constructor is private
    private static readonly Lazy<Foo> _instance = new Lazy<Foo>(() => new Foo());
    public static Foo Current => _instance.Value;

    private Foo()
    {
        // Don't allow calling code to new
    }
}
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
0

If you look at the summary for the two constructors in question...

// Summary:
//     Provides support for lazy initialization.
//
// Type parameters:
//   T:
//     Specifies the type of object that is being lazily initialized.
public class Lazy<T> {
    // Summary:
    //     Initializes a new instance of the System.Lazy<T> class. When lazy initialization
    //     occurs, the default constructor of the target type is used.
    public Lazy();
    //
    // Summary:
    //     Initializes a new instance of the System.Lazy<T> class. When lazy initialization
    //     occurs, the specified initialization function is used.
    //
    // Parameters:
    //   valueFactory:
    //     The delegate that is invoked to produce the lazily initialized value when
    //     it is needed.
    //
    // Exceptions:
    //   System.ArgumentNullException:
    //     valueFactory is null.
    public Lazy(Func<T> valueFactory);
}

That said, the main difference is what you can do to the type in the second constructor

eg...

new Lazy<Foo>(() => new Foo(){ SomeProperty = someValue} );

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

...which would differ from the default constructor.

Also, if the type doesn't have a default constructor with no parameters then then new Lazy<T>() may fail.

Nkosi
  • 235,767
  • 35
  • 427
  • 472