2011-07-14 26 views
29

Chciałbym użyć Lazy T do implementacji zapamiętywania, ale funkcja inicjalizacji wydaje się wymagać statycznego kontekstu.dlaczego Lazy <T> jest ograniczone do kontekstów statycznych?

Na przykład, następujący kod odmawia skompilować, ostrzegając, że członkowie niestatyczny i b są niedostępne. Nie jest dla mnie jasne, dlaczego tak jest, ponieważ obiekt Lazyjest samym elementem instancji i nie ma widoczności w kontekście statycznym.

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

Błąd tutaj nie występuje w Lazy, ale w wyrażeniu lambda. W kontekście lambda "a" i "b" jeszcze nie istnieją. – MattDavey

Odpowiedz

32

inicjatorów obiektu poza konstruktora (lub metody) musi odnosić się wyłącznie do członków statycznych. Dzieje się tak dlatego, że instancja nie została zbudowana, dopóki konstruktor nie zostanie uruchomiony, dlatego pola nie są jeszcze "gotowe" i dlatego nie można się do nich odwoływać. Pola statyczne działają, ponieważ są inicjowane przed polami.

Należy zauważyć, że błąd nie jest spowodowany przez Lazy<T>, jest on spowodowany wyrażeniem lambda. Obejściem problemu (i właściwym sposobem wykonania tego) jest zainicjowanie Result w konstruktorze.

+5

Dla ChessHound: To jest DLACZEGO kod nie działa. Nie ma to nic wspólnego z typem Lazy. –

11

nie wiem dlaczego kod nie działa, ale to powinno działać:

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

Po to, by rozwinąć odpowiedź @ Ondry, można ją wykorzystać również w fabryce iniekcyjnej. Jedno zastrzeżenie - bądź ostrożny względem względnej długości życia leniwego i fabrycznego:

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

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