Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Lazy Loading in C#

0.00/5 (No votes)
3 Nov 2011 1  
Lazy loading is a design pattern that helps a developer to delay initialization of an object until the program actually needs the object.

Introduction

The “Lazy Loading” design pattern actually equips the developer with the art of providing data only when a property is called for. In other words, it is a on-demand loading. It is an efficient technique to improve performance.

Using the code

For the explanation, I have taken a simple scenario. Say we have classes PersonalLoan and Loan, as shown below.

public class PersonalLoan 
{ 
    public string AccountNumber { get; set; }
    public string AccounHolderName { get; set; }
    public Loan LoanDetail { get; set; }       
    public PersonalLoan(string accountNumber)
    {
        this.AccountNumber = accountNumber;
        this.AccounHolderName = getAccounHolderName(accountNumber);
    } 
}
public class Loan
{
    public string AccountNumber { get; set; }
    public float LoanAmount { get; set; }
    public bool IsLoanApproved { get; set; }
    public Loan(string accountNumber)
    { 
        Console.WriteLine("loan class constructor called.....");
        this.AccountNumber = accountNumber;
        this.LoanAmount = 1000;
        this.IsLoanApproved = true;
        Console.WriteLine("loan object created.....");
    }
}

For explanation's sake, we will assume that AccountNumber and AccounHolderName are not so costly operations in terms of memory occupation and time consumption. On the other hand, LoanDetail is a costly operation and is not used so often. So while designing a class, we may expect that it is better not to have the detail and to populate it when the object property “LoadDetail” is accessed. Please note that the PersonalLoan constructor does not load the LoanDetail property right this point.

In order to archive LazyLoading, we need to change our code a little and it should look like:

public class PersonalLoan
{ 
    private Loan _loanDetail;
    public string AccountNumber { get; set; }
    public string AccounHolderName { get; set; }
    public Loan LoanDetail 
    { 
        get { return _loanDetail ?? (_loanDetail = new Loan(this.AccounNumber)); }
    }
    public PersonalLoan(string accountNumber)
    {
        this.AccounNumber = accountNumber;
        this.AccounHolderName = getAccounHolderName(accountNumber);
    }
} 

In this way, we make sure that “LoanDetail” will be populate only when the property is called rather than when the object for “PersonalLoan” is instantiated. For details, please check PersonalLoan.cs in the attached project.

Now taking this a step ahead, let's look what .NET 4.0 has in this respect. 4.0 introduces a “Lazy<T>” class to support lazy initialization, where “T” specifies the type of object that is being lazily initialized. This is a new feature of C# 4.0 and it can be used when we are working with large objects. The implementation is quite similar to what we have done in the last example.

public class PersonalLoanLazyClass
{
    private readonly Lazy<Loan> lazyLoan;
    public string AccountNumber { get; set; }
    public string AccounHolderName { get; set; }
    public Loan LoanDetail
    {
        get { return this.lazyLoan.Value; }
    }        
    public PersonalLoanLazyClass(string accountNumber)
    {
        Console.WriteLine("PersonalLoanLazyClass Object Initializ: call to costructor....");
        this.AccountNumber = accountNumber;
        this.AccounHolderName = getAccounHolderName(accountNumber);
        this.lazyLoan = new Lazy<Loan>(() => new Loan(this.AccountNumber));
        Console.WriteLine("Completed initialization.......");
    }
}

For details, please check PersonalLoanLazyClass.cs in the attached project. You can check out lazy loading by adding the following lines of code to the executing program:

static void Main(string[] args)
{
    var personalLoan = new PersonalLoanLazyClass("123456789");
    Console.WriteLine("\n\n.......................Press Enter " + 
            "to continue.......................\n\n");
    Console.Read();
    Console.WriteLine(personalLoan.LoanDetail.LoanAmount.ToString());
    Console.Read();
    Console.Read();
}

Output:

output.png

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here