2011-07-14 5 views
29

私はLazy Tを使用してメモを実装したいと思いますが、初期化関数は静的コンテキストを必要とするようです。なぜLazy <T>は静的コンテキストに制約されていますか?

は、例えば、次のコードは、非静的メンバBがアクセス不能であることを警告し、コンパイルすることを拒否する。 Lazyオブジェクトがインスタンスメンバーそのものであり、静的コンテキストでの可視性がないため、なぜこれがそうであるのかはわかりません。

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

ここでのエラーはレイジーではなくラムダ式です。ラムダ「a」と「b」の文脈では、まだ存在しない。 – MattDavey

答えて

32

オブジェクト初期化子は、静的メンバーのみを参照する必要があります。これは、コンストラクタが実行されるまでインスタンスが構築されていないため、フィールドが「準備ができていません」ため、参照できません。静的フィールドは、フィールドの前に初期化されるため動作します。

エラーはLazy<T>によって引き起こされないことに注意してください。これはラムダ式に起因しています。回避策(これを行う適切な方法)は、コンストラクタでResultを初期化することです。

+5

ChessHoundの場合:これはコードが機能しない理由です。レイジー型とは何の関係もありません。 –

11

私はあなたのコードが動作しない理由を知っているが、これは動作するはずドント:コンストラクタ(またはメソッド)外

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

@ Ondraの回答を拡張するだけで、注入された工場でも使用できます。注意すべきことは、遅延と工場の相対的な寿命には注意が必要です。

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

    // Ctor 
    public SomeClass(ISomeFactory factory) 
    { 
    _lazyField = new Lazy<ISomeDependency>(() => factory.Create()); 
    } 
} 
関連する問題