2011-12-15 122 views
3

我發現異常消息不能在C#空,並試圖此異常與空消息

var ex = new Exception(null); 
Console.WriteLine(ex.Message); 

我收到以下消息後:

類型的異常「的System.Exception '被拋出。

但是,在這種情況下,

var ex = new Exception(string.Empty); 
Console.WriteLine(ex.Message); 

的消息只是空的。

這是怎麼解釋的?你認爲這是預期的行爲?

+1

檢查出「異常」與.NET反射器或Telerik JustDecompile ctor) – kol 2011-12-15 15:34:28

回答

4

其他的答案(不包括從chopikadze答案)似乎是基於事實的誤讀。這兩個例子都沒有拋出異常。

相反,在第一個示例中,構造的異常ex正在提供消息,因爲構造函數的消息參數的值爲null。該消息是「類型'異常'System.Exception'被拋出」。

當對象引用爲空時,有一些回退行爲是一種相當普遍的做法,所以這就是「如何解釋」。當然,是否「預期」取決於您的期望。

在處理異常過程中拋出異常可能會產生問題,因此框架設計人員必須選擇這種行爲來減少這種可能性。坦率地說,如果我們都必須承擔異常信息可能爲空的可能性,那將是一場噩夢。

編輯

行爲也會記錄在the remarks for the Message property:「如果沒有消息被提供給構造當前情況下,系統將提供正在使用當前系統區域性格式化的默認消息。」

我查看了CLI規範和C#規範,並且我沒有發現消息具有非空返回值的要求,所以我認爲支持該行爲是框架設計決策的視圖。

2

string.Empty不爲空它是一個常數爲""

你的第一個例子是給一個默認的消息,你的第二個例子是一個空字符串

+3

第一個示例是* not *產生空引用異常;構造的異常`ex`提供了一條消息,因爲消息參數爲空,所以對'ex.Message`的調用返回字符串'拋出'System.Exception'類型的異常。 – phoog 2011-12-15 15:41:32

+0

是的,它包裝了一個空引用,因爲他正試圖向控制檯寫入一個空字符串.... – Maess 2011-12-15 15:55:14

+0

Console.WriteLine((string)null);不拋出異常。沒有新的異常,Message屬性只返回另一個字符串,而不是null – chopikadze 2011-12-15 15:57:58

3

實際上構造函數不需要字符串,你絕對可以肯定使用null。這是Exception類的reflectored部分:「類型的異常‘System.Exception的’被拋出」

internal string _message; 

public Exception(string message) 
{ 
    this.Init(); 
    this._message = message; 
} 


private void Init() 
{ 
    this._message = null; 
    this._stackTrace = null; 
    this._dynamicMethods = null; 
    this.HResult = -2146233088; 
    this._xcode = -532462766; 
    this._xptrs = IntPtr.Zero; 
    this._watsonBuckets = null; 
    this._ipForWatsonBuckets = UIntPtr.Zero; 
    this._safeSerializationManager = new SafeSerializationManager(); 
} 

public virtual string Message 
{ 
    [SecuritySafeCritical] 
    get 
    { 
     if (this._message != null) 
     { 
      return this._message; 
     } 
     if (this._className == null) 
     { 
      this._className = this.GetClassName(); 
     } 
     return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className }); 
    } 
} 

所以,如果你使用null作爲構造消息,本地化的字符串像將被用作消息。這意味着 - 仍然有你的異常,而不是另一個,但它的屬性消息返回另一個(計算)的值,而不是構造函數的空值。

我認爲它是由設計(也許是在另一個地方使用)定義的Exception.Message應該始終不爲空。因此,如果我們想讓開發人員使用Exception類的默認構造函數(例如,用於反射或稍後允許填充屬性),但我們也希望Message始終不爲空 - 我們應該使用某些東西來包裝Message。我認爲,消息使用的可能位置之一是在發生異常之後顯示的默認對話框。這種方式可以使用只是消息屬性,而不是檢查 - 是消息屬性等於空等