5 votes

Propriété paresseuse nécessitant "ceci".

Voici un exemple d'une propriété que j'ai, codée aussi simplement que possible

private IEnumerable<int> _blocks;
private bool _blocksEvaluated;
public IEnumerable<int> Blocks
{
    get
    {
        if (!_blocksEvaluated)
        {
            _blocksEvaluated = true;
            _blocks = this.CalculateBlocks(0).FirstOrDefault();
        }
        return _blocks;
    }
}

C'est verbeux ; j'aimerais le rendre plus concis si possible. Le texte suivant serait acceptable...

private Lazy<IEnumerable<int>> _blocks = 
    new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());

... mais il ne compile pas.

Le mot clé "this" n'est pas valide dans une propriété statique, une méthode statique ou un initialisateur de champ statique.

J'ai donc trouvé ce qui suit

struct MyLazy<TResult>
{
    private bool evaluated;
    private TResult result;

    public TResult Evaluate(Func<TResult> func)
    {
        if (!evaluated)
        {
            evaluated = true;
            result = func();
        }
        return result;
    }
}

private MyLazy<IEnumerable<int>> _blocks;
public IEnumerable<int> Blocks
{
    get { return _blocks.Evaluate(() => this.CalculateBlocks(0).FirstOrDefault()); }
}

Ce que je préfère, mais y a-t-il une meilleure façon de faire ?

Note - Je réalise que les structs mutables sont généralement maléfiques, mais ils semblent vraiment utiles pour ce problème particulier.

6voto

Michael Gunter Points 5175

Il suffit d'initialiser votre champ dans le constructeur.

public class MyClass
{
    public MyClass()
    {
        _blocks = new Lazy<IEnumerable<int>>(() => this.CalculateBlocks(0).FirstOrDefault());
    }

    private readonly Lazy<IEnumerable<int>> _blocks;
}

4voto

Servy Points 93720

Vous ne pouvez pas utiliser this lors de l'initialisation d'un champ d'instance, mais vous pouvez simplement l'initialiser dans le constructeur pour résoudre ce problème.

private Lazy<IEnumerable<int>> _blocks;

public MyClass()
{
   _blocks = new Lazy<IEnumerable<int>>(
         () => this.CalculateBlocks(0).FirstOrDefault());
}

public IEnumerable<int> Blocks
{
    get
    {
        return _blocks.Value;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X