SoFunction
Updated on 2025-03-06

How to use Lazy in C#

Delay initialization is a technique that delays the creation of an object until the first time it needs it. In other words, the initialization of an object occurs when it is really needed. It is worth noting that the terms delay initialization and delay instantiation mean the same - they can be used interchangeably. By using the delay initialization technology, unnecessary computing and memory consumption of the application can be avoided. In this article, we will discuss how to use delay initialization in C#.

Some friends may be confused after hearing these. Next, use a simple example to understand the lazy loading scenario. Consider the following two classes, Customer and Order. The Customer class contains an Orders attribute. A person will definitely have a lot of orders, which means it may contain a lot of data. It even needs to connect to the database to obtain Orders records. In this scenario, there is no need to bring complete orders to everyone in the customer collection. This initialization overhead is huge. The optimization point is to not load Orders, and it will not be filled as needed until some customers really need Orders.

Using Lazy<T>

You can write a piece of logic yourself to implement delayed initialization. It is unnecessary after .Net Framework 4.0, because Lazy<T> is already provided under the System namespace, and it is thread-safe. You can use this class to delay resource-intensive objects creation on demand.

When using Lazy<T>, the T here is the set you want to delay, so how to load on demand? Just call Lazy<T>.Value, the following code snippet shows how to use Lazy<T>.

Lazy<IEnumerable<Order>> orders = new Lazy<IEnumerable<Order>>();
IEnumerable<Order> result = ;

Now, consider the following two classes: Author and Blog. An author can write many articles, so there is a one-to-many relationship between these two classes. The following code snippet shows this relationship.

  public class Author
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public List<Blog> Blogs { get; set; }
  }
  public class Blog
  {
    public int Id { get; set; }
    public string Title { get; set; }
    public DateTime PublicationDate { get; set; }
  }

It is worth noting that mapping the one-to-many relationship to the object model in a relational database is to add a List Blogs attribute to the Author class. Using this attribute, Author can maintain one or more Blog instance objects, right?

Now assume that only the basic information of Author needs to be displayed on the user interface, such as: (firstname, lastname, address). In this scenario, it is meaningless to load a collection of Blogs on Author objects. When Blogs really need to be loaded, execution can be executed immediately. The following shows the usage of Lazy<Blog> Blogs.

  public class Author
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public Lazy<IList<Blog>> Blogs => new Lazy<IList<Blog>>(() => GetBlogDetailsForAuthor());
    private IList<Blog> GetBlogDetailsForAuthor(int Id)
    {
    //Write code here to retrieve all blog details for an author.
    }
  }

Use universal Lazy

Next let's see how to implement singleton pattern using generic Lazy. The StateManager below is thread-safe. To demonstrate delayed initialization, I used a static constructor to make sure the C# compiler does not mark it as beforefieldinit.

  public sealed class StateManager
  {
    private StateManager()
    {
    }

    public static StateManager Instance
    {
      get
      {
        return ;
      }
    }
    private class Nested
    {
      static Nested()
      {
      }
      internal static readonly StateManager obj = new StateManager();
    }
  }

Next I use Lazy<T> to wrap the StateManager, and you will find that using Lazy<T> to do delayed initialization is really too simple. . .

  public class StateManager
  {
    private static readonly Lazy<StateManager> obj = new Lazy<StateManager>(() => new StateManager());
    private StateManager() { }
    public static StateManager Instance
    {
      get
      {
        return ;
      }
    }
  }

You can view the Instance property of the above code. It is made into a read-only property. At the same time, you should also note that it is also a read-only property.

  public class Lazy<T>
  {
    public T Value
    {
      get
      {
        if (_state != null)
        {
          return CreateValue();
        }
        return _value;
      }
    }
  }

Delay initialization is a very good performance optimization technology. It allows you to delay those resource-intensive objects until you really need to load them. Everyone can use them in their own scenarios!

Translation link:/article/3227207/

This is the end of this article about how to use Lazy in C#. For more related C# Lazy content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!