2

In one website I read:

Lady loading is the concept of delaying the loading of an object until we need this data. In other words, we load the object on demand, rather than unnecessarily loading data earlier.

I want to try using Lazy Loading in my simple console app.

Student Class

 public class Students
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public string PESEL { get; set; }

        private Lazy<List<Students>> LazyStudents;
        

        public Students()
        {
           
        }

        public List<Students> StudentsProperty
        {
            get
            {
                if (LazyStudents == null)
                    LazyStudents = new Lazy<List<Students>>(() => LoadStudensList());
                return LazyStudents.Value;
            }
        }

        public List<Students> LoadStudensList()
        {
            List<Students> tempStudentsList = new List<Students>();
            tempStudentsList.Add(new Students() { Name = "Adam", Surname = "Wróbel", PESEL = "96120904999" });
            tempStudentsList.Add(new Students() { Name = "Edyta", Surname = "Urbańczyk", PESEL = "76354736458" });
            tempStudentsList.Add(new Students() { Name = "Gabriela", Surname = "Rydwańska", PESEL = "72637284923" });
            tempStudentsList.Add(new Students() { Name = "Dawid", Surname = "Rytel", PESEL = "62736482732" });

            return tempStudentsList;
        }
    }

Program and Main() method:

 class Program
    {
        static void Main(string[] args)
        {
            Students students = new Students();
            
            Console.WriteLine("Hello World!");
            foreach (var items in students.StudentsProperty)
            {
                    Console.WriteLine($"Imię: {items.Name}");
                    Console.WriteLine($"Nazwisko: {items.Surname}");
                    Console.WriteLine($"PESEL: {items.PESEL}");
                    Console.WriteLine("");
            }

            Console.WriteLine("Hello World!");
        }
    }

I suppose that i use Lazy Loading, when i create new object of Students class StudentsProperty (return elements from Lazy List) still empty. Elements to LazyList will be added when i use method using StudentsProperty

 foreach (var items in students.StudentsProperty)
            {
                    Console.WriteLine($"Imię: {items.Name}");
                    Console.WriteLine($"Nazwisko: {items.Surname}");
                    Console.WriteLine($"PESEL: {items.PESEL}");
                    Console.WriteLine("");
            }

I Add breakpoint before foreach loop and i see that StudentsProperty has elements: enter image description here

Have I implemented lazy loading incorrectly or do I understand something wrong?

8
  • Can you clarify this statement?: "I suppose that i use Lazy Loading, when i create new object of Students class StudentsProperty (return elements from Lazy List) still empty" Commented Jun 23, 2021 at 8:43
  • 5
    You are misusing the Lazy<T> class by deferring instantiation of it. It already handles the lazy aspect, but you are also doing that yourself by checking for null and instantiating it in StudentsProperty. You should instantiate the Lazy<T> at the field's point of declaration. As for why you can see the StudentsProperty property - the debugger is accessing it and so of course it gets instantiated, because the debugger is causing that! Commented Jun 23, 2021 at 8:44
  • You could probably go through some of the examples to understand the concept than understanding it just theoratically codeproject.com/Articles/652556/Can-you-explain-Lazy-Loading Commented Jun 23, 2021 at 8:44
  • For starters, having Lazy means you no longer need any kind of null check -- just do readonly Lazy<..> = new Lazy(...). Creating a Lazy lazily is superfluous. And second -- at the breakpoint, if you ask the debugger for StudentsProperty -- you're asking for the data, so of course it appears! Set a breakpoint only in LoadStudensList without inspecting expressions, step over Main, and see when it's called. Commented Jun 23, 2021 at 8:44
  • Lazy<T> is basically just a shortcut for if (x == null) x = new List<T>() . As others already noted, you can remove your null check. Commented Jun 23, 2021 at 8:45

1 Answer 1

1

Lazy.Value is when the lazy gets evaluated.

  LazyStudents = new Lazy<List<Students>>(() => LoadStudensList());
  return LazyStudents.Value;

doesn't make any sense. In the first line you say "evaluate when it's needed" and the second line says "I need it now".

By null checking you've did all the lazy evaluation on your own. Use either this:

    private Lazy<List<Students>> LazyStudents = new Lazy<List<Students>>(() => LoadStudensList());

    public List<Students> StudentsProperty
    {
        get
        {
            return LazyStudents.Value;
        }
    }

or this:

    private List<Students> LazyStudents;

    public List<Students> StudentsProperty
    {
        get
        {
            if (LazyStudents == null)
                LazyStudents = LoadStudensList();
            return LazyStudents;
        }
    }

They're supposed to be conceptually the same thing. Except multithreading safeguards, debugging and probably other pesky details, that make no difference most of the time.

The issue why you see values in debugger is bit more complicated. Looking at the Lazy source, it should display null in debugger, thanks to internal T ValueForDebugDisplay. However, you're NOT looking at value of lazy. By looking at at Students.StudentsProperty you're looking at your get and debbuger evaluates getters and your getter forces Lazy to evaluate. You've bypassed all that debugging code that MS had created for us. Expose the Lazy directly, it's meant to be. Or, instead of debugger, put a log in LoadStudensList()

Bottom line: Lazy is lazy only until Value gets called.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.