2016-07-27 120 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'爲空。當您執行'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爲空。有關靜態初始化的一些討論,請參閱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

感謝您的解釋,現在我明白了執行命令。 – abx78