When to use C Lazy< > #

Where is a good scenario to use the C#initializer Lazy<>?

I ask this because, I understand the concept behind lazy loading (delay the instance of an object to only when the same is needed), but I haven't had the need to use yet, so I'd like an example of a good situation from where to implement.

For example, reading the documentation here: lazy initialization

There are two examples:

" When you have an object that is expensive to create, and the program might not use it "

Or in free translation,

" when you have an object that is costly to create and may not be used "

In this case, it would be enough to use a simple if or even create it unless it will use, correct?

"When you have an object that is expensive to create, and you want to defer its creation until after other expensive operations have been completed "

Or in free translation

" when you have an object that is costly to create and you want postpone its creation until other costly operations have been completed "

I can just change the place where the object was created, do this asynchronously, in another thread , etc, i.e. various ways around this.

Wanted an example of a situation where the Lazy would make the difference, which would solve if you need a lot of implementation, or something complex to get around the problem.

Author: Maniero, 2019-12-19

2 answers

What is not so clear in all this already exposed is that this class should be used whenever the data may or may not be used in the execution of the moment. It is not just a matter of leaving for later, it is leaving for later because who knows it may not even be necessary.

I think it was clear that it is only worth doing this if the startup is expensive, so it comes from an expensive operation of a database, or from the internet or service that you do not have control of the time spent. It is like the use of async, it is worth it only if the operation takes a long time.

In general fields of a structure are initialized at the time of its creation so any situation that that may or may not be used can be useful.

But care is needed because people can start using this to compensate for bad design. There is a situation that what may or may not be used, and therefore delayed, must be part of another object.

Examples

The most common example of using this type is in ORMs already that the data may or may not be used so it would be better not to ask the DB right away. On the other hand, and this is one of the criticisms that is made to ORM, this can harm the performance because it makes you have more access to the database instead of bringing everything at once. Of course you usually have this ready and don't use Lazy in your code, unless you're doing an ORM, and even then you might even prefer a more sophisticated control mechanism, Lazy it's fine simple .

I found a example in the SO that shows well that everything that uses the Lazy can do without it:

public sealed class Singleton {
    private static readonly Lazy<Singleton> instanceHolder = new Lazy<Singleton>(() => new Singleton());
    private Singleton() { ... }
    public static Singleton Instance => instanceHolder.Value;
}

And without:

private static object lockingObject = new object();
public static LazySample InstanceCreation() {
    if (lazilyInitObject == null) {
        lock (lockingObject) {
            if (lazilyInitObject == null) lazilyInitObject = new LazySample();
        }
    }
    return lazilyInitObject;
}

I put on GitHub for future reference.

I do not know if the example is so good to show the practice (the goal was not that) because the object is only created when it is called once and in this case usually when it calls it already needs to be used.

Is the same local use case (method), you can put at the time you need. I'm not saying you should never use it, but in general you don't need Lazy. The need for this type has more to do with the fact that you do not know the exact moment you need. Almost all examples of local use is only to demonstrate the mechanism and not the practice of use.

If you have a static object it can be useful because by specification the initialization of that object can be done at any time from the initialization of the application to the use of that object. Lazy would be a way to ensure that the actual startup only occurs at the time of use.

This is because formal initialization occurs without its control, but what is initialized is object Lazy which is very cheap, and the object that matters (the T) will be initialized when it is used, the Lazy controls this.

So trying to give a practical use, think that you access the data of a bank chain. In general you only access the account data, but in some cases you will be able to access his transactions, but for some reason the list of these transactions were placed in the account probably to facilitate access and not have an external object.

public Lazy<IList<Transacoes>> trancasoes => new Lazy<IList<Transacoes>>(() => ObtemTranscaoes(this.Id));

I assume that this method takes time to execute.

Is that a good example? I think not because it seems to be design bad only, but if it had any reason to keep the transactions close to the account then it makes sense. Most of the examples we found are not necessary even.

An example that can be useful is when there is memoization. But it can also abuse this and in many cases needs a sophistication that Lazy does not solve. In others the time he spends is derisory to need the lazy boot.

Is like design pattern (what this is already ready for use provided by the library), you should know that it exists, but not leave applying because it exists. In the rare cases it should be used you have knowledge and you will see that ali applies, or else that your design is bad and you should rethink it.

 4
Author: Maniero, 2020-06-11 14:45:34

Maybe a situation that I see that this can be very useful and useable is with Func / Delegate, where you can pass a Lazy object that you can or can not use it inside your Func.

Thus, within it you could do the proper validations to start or not it as well as the manipulation, however, there are other ways to get around this, but this is a very applicable way.

 1
Author: Brian Goncalves, 2019-12-19 12:55:56