When Should I Use Lazy<T>

When should I use LazyT?

You typically use it when you want to instantiate something the first time its actually used. This delays the cost of creating it till if/when it's needed instead of always incurring the cost.

Usually this is preferable when the object may or may not be used and the cost of constructing it is non-trivial.

Should LazyT be preferred to lazy initialization in a getter?

Lazy<> can be useful since it inludes support for multithreading too, something you have to build yourself when creating your own 'lazy'.

For code that doesn't need multi-threading, this would be the best performing and readable code in my opinion (using the null-coalescing operator).

return variable ?? (variable = new ClassName());

Note that since this code isn't thread safe, you could end up calling new ClassName() multiple times.

You should introduce locking then, and the readability will decrease. If it is just for readability, Lazy<> might be not that bad in that case.

Also, Lazy<> prevents you to use the backing field in the case of cached properties.

LazyT why does it get FuncT

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())
{
}
}

LazyInitializer vs LazyT class. When to use each one

Lazy<T> (MSDN) is a generic wrapper which allows creating an instance of T on demand by holding a T factory method (Func<T>) and calling it when Value property getter is accessed.

LazyInitializer - static class with a set of static methods, this is just a helper which uses Activator.CreateInstance() (reflection) able to instantiate a given type instance. It does not keep any local private fields and does not expose any properties, so no memory usage overheads.

Worth noting that both classes uses Func<T> as instance factory.

MSDN says in few words about LazyInitializer class:

These routines avoid needing to allocate a dedicated,
lazy-initialization instance, instead using references to ensure
targets have been initialized as they are accessed.

PS:
I found interesting a way how LazyIntiializer checks whether instance already initialized, it just compare a passed in reference to a default(T), nice:

private static T EnsureInitializedCore<T>(ref T target, Func<T> valueFactory) 
where T : class
{
T t = valueFactory();
if (t == null)
{
throw new InvalidOperationException(Environment.GetResourceString("Lazy_StaticInit_InvalidOperation"));
}

Interlocked.CompareExchange<T>(ref target, t, default(T));
return target;
}

What seems strange to me, it creates a new instance each time before an actual check:

T t = valueFactory(); 
// ... and only then does check

Should I use LazyT in a controller where a class may not be used?

I would definitely use the lazy initialization for the validation service. For the exception handler, you can go either way - exceptions are expected. The nice thing about lazy initialization is that your code is more responsive and uses fewer resources. The downside is to learn a new class. Once you've learned it, you can use in many places.

Why to use LazyT for an enum?

As there seems to be some confusion why this might be a good idea, here is a version doing the same without Lazy:

private SomeEnum? _value = null;

private SomeEnum CostyCalculation()
{
return ...;
}

public SomeEnum MyVar
{
get
{
if (_value == null)
_value = CostyCalculation();
return _value.Value;
}
}

As you can see the value is only calculated when you first need it and once you have it you don't need to recalculate it again.

Lazy does the same thing with a slight different syntax/usage:

    private Lazy<SomeEnum> _value = new Lazy<SomeEnum>(CostyCalculation);

private SomeEnum CostyCalculation()
{
return SomeEnum.E1;
}

public SomeEnum MyVar
{
get
{
return _value.Value;
}
}

Disadvantages of LazyT?

I'll expand a bit on my comment, which reads:

I've just started using Lazy, and find that it's often indicative
of bad design; or laziness on the part of the programmer. Also, one
disadvantage is that you have to be more vigilant with scoped up
variables, and create proper closures.

For example, I've used Lazy<T> to create the pages the user can see in my (sessionless) MVC app. It's a guiding wizard, so the user might want to go to a random previous step. When the handshake is made, an array of Lazy<Page> objects is crated, and if the user specifies as step, that exact page is evaluated. I find it delivers good performance, but there are some aspects to it that I don't like, for example many of my foreach constructs now look like this:

foreach(var something in somethings){
var somethingClosure = something;
list.Add(new Lazy<Page>(() => new Page(somethingClosure));
}

I.e. you have to deal with the problem of closures very proactively. Otherwise I don't think it's such a bad performance hit to store a lambda and evaluate it when needed.

On the other hand this might be indicative that the programmer is being a Lazy<Programmer>, in the sense that you'd prefer not thinking through your program now, and instead let the proper logic evaluate when needed, as with example in my case - instead of building that array, I could just figure out just what that specific requested page would be; but I chose to be lazy, and do an all in approach.

EDIT

It occurs to me that Lazy<T> also has a few peculiars when working with concurrency. For example there's a ThreadLocal<T> for some scenarios, and several flag configurations for your particular multi-threaded scenario. You can read more on msdn.



Related Topics



Leave a reply



Submit