Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use System.Lazy with Setter to Lazy Initialization of List in POCO Entities?

I want to use System.Lazy to Lazy Initialization of my List in my Entites:

public class Questionary
{
    private Lazy<List<Question>> _questions = new Lazy<List<Question>>(() => new List<Question>());

    public IList<Question> Questions { get { return _questions.Value; } set { _questions.Value = value; } }
}

The problem is on my SETTER, get this error: The property 'System.Lazy<T>.Value' has no setter

If i want to do MyInstance.Questions = new List<Question> { ... } ?

How do I proceed?

Update:

I'm trying to avoid that:

private IList<Question> _questions;

//Trying to avoid that ugly if in my getter:
public IList<Question> Questions { get { return _questions == null ? new List<Question>() : _questions; } set { _questions = value } }

I'm doing something wrong?

like image 492
Acaz Souza Avatar asked Jul 27 '11 13:07

Acaz Souza


People also ask

How do you initialize a Lazy?

Implementing a Lazy-Initialized Property To implement a public property by using lazy initialization, define the backing field of the property as a Lazy<T>, and return the Value property from the get accessor of the property. The Value property is read-only; therefore, the property that exposes it has no set accessor.

What is lazy initialization C#?

Lazy initialization is a technique that defers the creation of an object until the first time it is needed. In other words, initialization of the object happens only on demand. Note that the terms lazy initialization and lazy instantiation mean the same thing—they can be used interchangeably.

How lazy initialization works in Java?

The Lazy Initialization technique consists of checking the value of a class field when it's being used. If that value equals to null then that field gets loaded with the proper value before it is returned.

How does Lazy t work?

The Lazy<T> object ensures that all threads use the same instance of the lazily initialized object and discards the instances that are not used.


2 Answers

You could do something like this:

public class Questionary
{
    private Lazy<IList<Question>> _questions = 
        new Lazy<IList<Question>>(() => new List<Question>());

    public IList<Question> Questions
    {
        get { return _questions.Value; }
        set { _questions = new Lazy<IList<Question>>(() => value); }
    }
}

However, I don't see why you need Lazy<T> here at all. There is no benefit in using it, because the initialization of a new List<T> should be the same as the initialization of a new Lazy<T>...

I think it would be enough to keep it as simple as this:

public class Questionary
{
    private IList<Question> _questions = new List<Question>();

    public IList<Question> Questions
    {
        get { return _questions; }
        set { _questions = value; }
    }
}

or

public class Questionary
{
    public Questionary()
    {
        Questions = new List<Question>();
    }

    public IList<Question> Questions { get; set; }
}
like image 142
Daniel Hilgarth Avatar answered Sep 20 '22 18:09

Daniel Hilgarth


It's not clear what you're trying to do. You can't set the value of a Lazy<T> - it's as simple as that. You can only ask it for a value, and it will execute the delegate you've provided the first time the values are requested.

Do you really need a setter in your class at all? Perhaps you just want:

public class Questionary
{
    private Lazy<List<Question>> _questions = 
        new Lazy<List<Question>>(() => new List<Question>());

    public IList<Question> Questions { get { return _questions.Value; } }
}
like image 25
Jon Skeet Avatar answered Sep 20 '22 18:09

Jon Skeet