類型初始值設定項引發異常

遇到了這個問題,這篇博文說得透徹。根據它,我發現是一個靜態變量初始化時出錯了,原因是程序使用了舊的配置文件,導致數據錯誤。

特此轉發。

原文地址:http://hi.baidu.com/charmingpeace/blog/item/2263d9bdb970570318d81f5d.html

 

-上午打開VS編譯程序的時候,突然出現了這個運行時錯誤“類型初始值設定項引發異常”。昨天還沒有這個錯誤呢,今天就突然出現,搞得我一頭霧水。上網搜了一下,發現有很多人遇到了這個問題。經過一番折騰解決了這個問題後,發現很多人都沒有意識到其癥結所在,於是寫這個隨筆,給大家點啓發,也給自己做個備忘。

症狀描述:
我的程序需要連接一臺MQ服務器(其實就是個臺式機,每天下班關機),如果服務器沒有開,程序就會拋出異常。以前編譯時老是忘開服務器,經常會出現MQ訪問失敗的異常。這次我原本以爲也是這個異常,沒想到出來的是“類型初始值設定項引發異常”。
今天的錯誤爲什麼會和以往不一樣呢?昨天臨下班時,把一個類的單件模式做了重構,使用了靜態初始化方法。代碼如下:

【轉】類型初始值設定項引發異常private static readonly WorkerManager instance = new WorkerManager();
【轉】類型初始值設定項引發異常
static WorkerManager() { }
【轉】類型初始值設定項引發異常
private WorkerManager()
【轉】類型初始值設定項引發異常
{
【轉】類型初始值設定項引發異常     Initialize();
【轉】類型初始值設定項引發異常}

【轉】類型初始值設定項引發異常
public static WorkerManager Instance
【轉】類型初始值設定項引發異常
{
【轉】類型初始值設定項引發異常    
get { return instance; }
【轉】類型初始值設定項引發異常}

訪問MQ的語句在Initialize方法裏,問題就應該出現在這裏了。

解決方法:
當然,把MQ服務器打開問題就解決了,但是究竟爲什麼會出現“類型初始值設定項引發異常”呢?
原來類的靜態成員在初始化時如果出現異常,訪問類的其它靜態成員或對該類進行初始化都會拋出這個異常。請看下面的代碼:

【轉】類型初始值設定項引發異常    public class Test
【轉】類型初始值設定項引發異常    
{
【轉】類型初始值設定項引發異常        
public static Foo Test1 = new Foo();
【轉】類型初始值設定項引發異常        
public static string Test2 = "Test2";
【轉】類型初始值設定項引發異常        
public string Test3 = "Test3";
【轉】類型初始值設定項引發異常        
public Test() { }
【轉】類型初始值設定項引發異常     }

【轉】類型初始值設定項引發異常
【轉】類型初始值設定項引發異常    
public class Foo
【轉】類型初始值設定項引發異常    
{
【轉】類型初始值設定項引發異常        
public Foo()
【轉】類型初始值設定項引發異常        
{
【轉】類型初始值設定項引發異常            
throw new Exception();
【轉】類型初始值設定項引發異常         }

【轉】類型初始值設定項引發異常     }

在訪問Test.Test2以及new Test()時都會拋出這個異常。我的代碼中,由於Initialize()出現異常,instance實例化失敗,所以訪問Instance時就拋出了這個異常。

總結:

TypeInitializationExeption在MSND中的描述爲:當類初始值設定項不能初始化類型時,將創建 TypeInitializationException 並向其傳遞由該類型的類初始值設定項引發的異常引用。

我們知道,類型初始化或者訪問類型的靜態成員時,都會對類中的其他靜態成員進行初始化,並執行靜態構造函數(如果有的話)。在這些過程中如果任一環節出現例如下面的代碼:

 class ClassHelper
     {
        
public static string Field = Do("Initial the static field");
        
public static string StaticString = "Initaial static string";
        
public string NonStaticString = "Initial non static string";
        
public ClassHelper()
         {
             NonStaticString
= "Change non static string in instance constructor";
             StaticString
= "Change static string in instance constructor";
         }
        
public static string Do(string field)
         {
             Console.WriteLine(field);
            
throw new Exception();
            
return field;
         }
     }

    

那麼產生TypeInitializationException的情況就包含以下幾種:

1. 訪問類的某一靜態成員,而其他靜態成員的初始化(或靜態構造函數中)產生異常。例如訪問ClassHelper.StaticString,由於靜態成員Field的初始化產生異常,因此調用ClassHelper.StaticString會拋出TypeInitializationException。

2. 訪問類的某一靜態成員,該靜態成員的初始化(或靜態構造函數中)產生異常。例如訪問ClassHelper.Field。

3. 對該類進行初始化,而類中的某個靜態成員初始化(或靜態構造函數中)產生異常。例如ClassHelper helper = new ClassHelper()。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章