0

According to Microsoft,

Lazy initialization of an object means that its creation is deferred until it is first used. (For this topic, the terms lazy initialization and lazy instantiation are synonymous.) Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.

Suppose I have a Product class and a Category class, and the relationship is one-to-many, which means that a Product object holds a Category object, and a Category object holds a collection of Product objects.

This is the code of the Product class:

class Product
{
    public string Code { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }

    public Category Category { get; set; }
} 

This is the code for the Category class:

class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }

    public ICollection<Product> Products { get; private set; }
}

In this scenario, the Product objects of the Category object is not always needed, so it does not always need to be always initialized. So, this is what I did:

class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }

    public ICollection<Product> products;
    public ICollection<Product> Products
    {
        get
        {
            if (products == null)
            {
                // retrieves the products from the database and stores it in field: products
            }
            return products;
        }
    }
}

By doing this, the Products is retrieved once and only when it is asked for right? Then, I read about Lazy Initialization, and I draft my Category class like so:

class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }

    public ICollection<Product> products;
    public Lazy<ICollection<Product>> Products => new Lazy<ICollection<Product>>(() => GetProductsByCategoryID(this.CategoryID));

    public ICollection<Product> GetProductsByCategoryID(int categoryID)
    {
        // retrieves the products from the database
    }
}

My questions are, how are these two implementations different? Does the lazy initialization provides a better performance or uses less memory?

Kinin Roza
  • 721
  • 3
  • 12
  • 1
    The main benefit of `Lazy` in that instance is that if two threads ask for the value at the same time, `GetProductsByCategoryID` will be called only once. The main downside is that if `GetProductsByCategoryID` throws an exception then all future requests will see that exception (which your first code block likely won't suffer from). I personally would use `LazyWithNoExceptionCaching` - https://stackoverflow.com/a/42567351/34092 . – mjwills Dec 30 '20 at 02:57
  • 2
    In either case, you are potentially breeding bad practice since you are not using async/await and you are blocking threads. You might want to think through what it would take to add async/await and then see how that determines your approach. – David L Dec 30 '20 at 03:04
  • @DavidL I will go though it. Does using async/await helps with memory allocations and computation as well? – Kinin Roza Dec 30 '20 at 03:08
  • 1
    No, it helps with threading throughput for I/O-bound calls. Since you are using Lazy (presumably to reduce concurrent threads requesting the same data), it makes sense to also eliminate blocked threads during I/O waits. – David L Dec 30 '20 at 03:14

0 Answers0