2016-07-27 4 views
0

Я получил этот кодЛенивый Свойство инициализации в статическом классе C#

public static class Logger 
{ 
    public static Func<ILogger> LoggerFactory; 
    private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(LoggerFactory); 

    public static ILogger Instance 
    { 
     get 
     { 
      return _log.Value; 
     } 
     public static ILogger ConfigureLogging(string AppName, Version AppVersion) 
     { 
      // stuff 
     } 
    } 
} 

Этот статический класс используется в приложении:

Logger.LoggerFactory =() => Logger.ConfigureLogging(AppName, AppVersion); 
Logger.Instance.Information("Starting application"); 

Я ожидаю, что первый ряд, чтобы установить LoggerFactory; однако при первой попытке записи в журнал исключение вызывается, потому что статический Func LoggerFactory еще не установлен.

Что не так с этим кодом?

Благодаря

+1

Потому что, когда вы создаете '_log',' LoggerFactory' имеет значение NULL. К тому времени, когда вы выполните 'Logger.LoggerFactory = ...' вы уже инициализировали '_log' –

+0

Вы можете попробовать:' private static readonly Lazy _log = new Lazy (() => LoggerFactory()); ' –

ответ

2

Быстрый и грязный исправить это было бы сделать это:

private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(() => LoggerFactory()); 

Lazy выполняет функцию, которая будет выполнена при первой попытке для доступа к Value, но в вашем коде вы передаете его null, потому что вы еще не инициализировали LoggerFactory. Статический инициализатор в вашем классе будет запускаться до того, как будет осуществлен доступ к любому из статических полей, поэтому ваша попытка доступа к LoggerFactory приведет к инициализации вашего поля _log (если он еще не был), в котором LoggerFactory имеет значение NULL. См., Например, here для обсуждения статической инициализации.

Вы можете отложить доступ к LoggerFactory, но завернув его в функцию.

+0

Очень ясно, спасибо @MattBurland – abx78

3

Вот порядок исполнения:

private static readonly Lazy<ILogger> _log = new Lazy<ILogger>(null); 
//LoggerFactory is null at this point 

Logger.LoggerFactory =() => Logger.ConfigureLogging(AppName, AppVersion); 
Logger.Instance.Information("Starting application"); 

и, таким образом, _log останется утратившим

+0

Спасибо за объяснение, теперь я понимаю порядок exec. – abx78

Смежные вопросы