开发者

why is Lazy<T> constrained to static contexts?

开发者 https://www.devze.com 2023-03-20 01:03 出处:网络
I\'d like to use Lazy T to implement memoization but the initialization function appears to require a static context.

I'd like to use Lazy T to implement memoization but the initialization function appears to require a static context.

For example, the following code refuses to compile, warning that non-static members a and b are inaccessible. It's not clear to me why this is so as the Lazy object is an instance member itself and has no visibility in a static 开发者_如何学Gocontext.

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


Object initializers outside a constructor (or method) has to refer to static members only. This is because the instance hasn't been constructed until the constructor is run, hence the fields are not "ready yet" and therefor cannot be referenced. Static fields work because they are initialized before fields.

Note that the error isn't caused by Lazy<T>, it is caused by the lambda expression. The workaround (and proper way of doing this) is to initialize Result in a constructor.


I don´t know why your code does not work, but this should work:

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


Just to expand on @Ondra's answer, this can be used with an injected factory as well. One caveat - be wary of the relative lifespans of the lazy and the factory:

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

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

精彩评论

暂无评论...
验证码 换一张
取 消