почему Lazy <T>ограничен статическим контекстом? - PullRequest
31 голосов
/ 14 июля 2011

Я бы хотел использовать Lazy T для реализации запоминания, но для функции инициализации требуется статический контекст.

Например, следующий код отказывается компилировать, предупреждая, что нестатические элементы a и b недоступны. Мне непонятно, почему это так, поскольку объект Lazy сам является элементом экземпляра и не имеет видимости в статическом контексте.

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

Ответы [ 3 ]

32 голосов
/ 14 июля 2011

Инициализаторы объектов вне конструктора (или метода) должны ссылаться только на статические члены. Это связано с тем, что экземпляр не был создан до тех пор, пока не будет запущен конструктор, поэтому поля еще не «готовы» и поэтому на них нельзя ссылаться. Статические поля работают, потому что они инициализируются перед полями.

Обратите внимание, что ошибка вызвана не Lazy<T>, а лямбда-выражением. Обходной путь (и правильный способ сделать это) заключается в инициализации Result в конструкторе.

12 голосов
/ 14 июля 2011

Я не знаю, почему ваш код не работает, но это должно работать:

    public class SomeExpensiveCalculation
    {
        private int a;
        private int b;
        public Lazy<int> Result;
        public SomeExpensiveCalculation()
        {
             Result = new Lazy<int>(() => a + b);
        }
    }
1 голос
/ 16 октября 2013

Просто, чтобы расширить ответ @ Ondra, это можно использовать и для инъекционной фабрики. Одно предостережение - остерегайтесь относительной продолжительности жизни ленивых и фабрики:

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

  // Ctor
  public SomeClass(ISomeFactory factory)
  {
     _lazyField = new Lazy<ISomeDependency>(() => factory.Create());
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...