31

Lazy Tを使用してメモ化を実装したいのですが、初期化関数には静的コンテキストが必要なようです。

たとえば、次のコードはコンパイルを拒否し、非静的メンバーaおよびbにアクセスできないことを警告します。Lazyオブジェクトはそれ自体がインスタンスメンバーであり、静的コンテキストでは可視性がないため、これがなぜそうなのかは私にはわかりません。

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

3 に答える 3

34

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

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

于 2011-07-14T07:44:23.313 に答える
12

コードが機能しない理由はわかりませんが、これは機能するはずです。

    public class SomeExpensiveCalculation
    {
        private int a;
        private int b;
        public Lazy<int> Result;
        public SomeExpensiveCalculation()
        {
             Result = new Lazy<int>(() => a + b);
        }
    }
于 2011-07-14T07:38:58.213 に答える
1

@Ondraの答えを拡張するために、これは注入されたファクトリでも使用できます。1つの注意点-怠惰な人と工場の相対的な寿命に注意してください:

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

  // Ctor
  public SomeClass(ISomeFactory factory)
  {
     _lazyField = new Lazy<ISomeDependency>(() => factory.Create());
  }
}
于 2013-10-16T09:00:12.103 に答える