Domanda perché Lazy è vincolato a contesti statici?


Mi piacerebbe usare Pigro T per implementare la memoizzazione ma la funzione di inizializzazione sembra richiedere un contesto statico.

Ad esempio, il seguente codice si rifiuta di compilare, avvertendo che i membri non statici un e B sono inaccessibili Non mi è chiaro perché sia ​​così come il Pigro oggetto è un membro di istanza stesso e non ha visibilità in un contesto statico.

public class SomeExpensiveCalculation
{
    private int a;
    private int b;
    public Lazy<int> Result = new Lazy<int>(() => a + b); //nope!
}

30
2017-07-14 07:30


origine


risposte:


Gli inizializzatori di oggetti all'esterno di un costruttore (o metodo) devono fare riferimento solo ai membri statici. Questo perché l'istanza non è stata costruita fino a quando non viene eseguito il costruttore, quindi i campi non sono ancora "pronti" e quindi non può essere referenziato. I campi statici funzionano perché sono inizializzati prima dei campi.

Si noti che l'errore non è causato da Lazy<T>, è causato dall'espressione lambda. La soluzione alternativa (e il modo corretto per farlo) è inizializzare Result in un costruttore.


32
2017-07-14 07:44



Non so perché il tuo codice non funziona, ma dovrebbe funzionare:

    public class SomeExpensiveCalculation
    {
        private int a;
        private int b;
        public Lazy<int> Result;
        public SomeExpensiveCalculation()
        {
             Result = new Lazy<int>(() => a + b);
        }
    }

11
2017-07-14 07:38



Solo per ampliare la risposta di @ Ondra, questo può essere utilizzato anche con una fabbrica iniettata. Un avvertimento: diffidare delle relative durate di vita dei pigri e della fabbrica:

public class SomeClass
{
  private readonly Lazy<ISomeDependency> _lazyField;

  // Ctor
  public SomeClass(ISomeFactory factory)
  {
     _lazyField = new Lazy<ISomeDependency>(() => factory.Create());
  }
}

1
2017-10-16 09:00