Какие преимущества предлагает Lazy <T> над стандартным ленивым экземпляром?

Рассмотрим этот пример, он показывает два возможных способа ленивой инициализации. За исключением того, что они являются потокобезопасными, существуют ли какие-либо конкретные преимущества использования Lazy <T> здесь?

class Customer {
    private decimal? _balance2;
    private static decimal GetBalanceOverNetwork() {
        //lengthy network operations
        Thread.Sleep(2000);
        return 99.9M;
    }

    public decimal? GetBalance2Lazily() {
        return _balance2 ?? (_balance2 = GetBalanceOverNetwork());
    }

    private readonly Lazy<decimal> _balance1 = new Lazy<decimal>(GetBalanceOverNetwork);

    public Lazy<decimal> Balance1 {
        get { return _balance1; }
    }
}

UPDATE:

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

Ответ 1

Это семантически более корректно.

Когда вы используете Nullable<decimal>, вы говорите, что значение null будет означать состояние "unevaluated". Хотя это обычное обращение, оно по-прежнему произвольно. Есть миллион других способов интерпретации null, поэтому вы должны, вероятно, объяснить где-нибудь (в документации или, по крайней мере, в качестве комментария), что означает нуль в этом случае.

Наоборот, когда вы используете Lazy<decimal>, ваши намерения ясны.