为什么Lazy <t>被约束到静态上下文?</t>

时间:2011-07-14 07:30:13

标签: c# .net-4.0 lazy-initialization

我想使用Lazy T来实现memoization,但初始化函数似乎需要静态上下文。

例如,以下代码拒绝编译,警告非静态成员 a b 不可访问。我不清楚为什么会这样,因为 Lazy 对象本身就是一个实例成员,并且在静态上下文中没有可见性。

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

3 个答案:

答案 0 :(得分:32)

构造函数(或方法)之外的对象初始值设定项只能引用静态成员。这是因为在构造函数运行之前尚未构造实例,因此字段不是“就绪”,因此无法引用。静态字段起作用,因为它们在字段之前初始化。

请注意,错误不是由Lazy<T>引起的,而是由lambda表达式引起的。解决方法(以及执行此操作的正确方法)是在构造函数中初始化Result

答案 1 :(得分:12)

我不知道为什么你的代码不起作用,但这应该有效:

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

答案 2 :(得分:1)

为了扩展@ Ondra的答案,这也可以用于注入的工厂。一个警告 - 警惕懒惰和工厂的相对寿命:

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

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