Chapter 2 - Item 13 : Use Proper Initialization for static Class Members

Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得

C# 提供了靜態建構子,讓建構靜態變數能夠更彈性且可靠。以下提供程式碼範例如何應用。

獨體模式:

public class MySingleton
{
    private static readonly MySingleton _theOneAndOnly = new MySingleton( );

    public static MySingleton TheOnly => _theOneAndOnly;

    // Set constructor to private that avoiding other object creates MySingleton.
    private MySingleton( )
    {
    }
}

當 Singleton 物件建構邏輯較為複雜時,可以利用靜態建構子幫助除錯(i.e. try catch)。

public class MySingleton2
{
    private static readonly MySingleton2 _theOneAndOnly;

    public static MySingleton2 TheOnly => _theOneAndOnly;

    static MySingleton2( )
    {
        try
        {
            _theOneAndOnly = new MySingleton2( );
        }
        catch ( Exception )
        {
            // Attempt to recovery.
        }
        finally
        {
            // Clean up.
        }
    }

    private MySingleton2( )
    {
    }
}
結論:
1. 靜態建構子若執行失敗會擲出 TypeInitializationException,若程式架構有機會出現此種錯誤;利用 try catch 回復,否則會造成程式運行失敗。

2. 由於靜態建構子由 CLR 呼叫,靜態建構子不能加入引數。

3. 如果有複雜且耗時的初始化工作,可使用 Lazy<T> 延遲初始化。