Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

C#: в чем отличие Lazy<T> от аналогичных реализаций?

#c_sharp


Здесь показан пример отложенной инициализации свойства класса, выглядит это так: 

private Lazy _someVariable =new Lazy(SomeClass.IOnlyWantToCallYouOnce);
public string SomeVariable {
    get { return _someVariable.Value; }
}


Возник вопрос: чем отличается вышеуказанная инициализация от например такой:

private string? _someVariable = null;
public string SomeVariable {
    get {
        if(_someVariable == null) {
            // здесь могу ошибаться, но думаю, что принцип понятен
            _someVariable = new SomeClass().IOnlyWantToCallYouOnce();
        }
        return _someVariable;
    }
}

    


Ответы

Ответ 1



У Lazy есть потокобезопасная версия, при реализации же ленивости вручную надо городить DCL и не забыть про volatile. Второй вариант использует null как маркер отсутствия значения. Если вдруг функция IOnlyWantToCallYouOnce() вернет null - она будет вызвана еще раз. У Lazy же null - такое же допустимое значение, как и любое другое, потому что маркер наличия значения хранится отдельно от самого значения. Lazy сохраняет не только результат нормального вычисления - но и исключение в случае ошибки, поэтому функция IOnlyWantToCallYouOnce будет вызвана только 1 раз чего бы не случилось. Решение же номер два в случае исключения при вызове ничего не сохранит и при повторном обращении попытается получить его еще раз. Иногда это полезно, иногда - вредно.

Комментариев нет:

Отправить комментарий