2012-11-07 214 views
55

在下面的代碼中,爲什麼兩個string.Format調用的行爲不一樣?在第一個,沒有例外拋出,但在第二個拋出ArgumentNullExceptionstring.Format如何處理空值?

static void Main(string[] args) 
{ 
    Exception e = null; 
    string msgOne = string.Format("An exception occurred: {0}", e); 
    string msgTwo = string.Format("Another exception occurred: {0}", null); 
} 

有人能幫我理解兩者之間的區別嗎?

+7

機會是你打的第二個例子,'String.Format'的['params'覆蓋](http://msdn.microsoft.com/en-us/library/b1csw23d.aspx)在繼續迭代集合和插入值之前測試數組是否已填充。 –

+0

@BradChristie你應該寫這個答案。 – erikkallen

回答

43

我在這裏猜測,但它看起來是你打的重載呼叫的差異。 String.Format有多個重載,它只是你打的。

在第一個示例中,您打到String.Format(string,object)是有意義的。通過提供null

在第二個例子中你最有可能打String.Format(string,params object[])其中,每個文檔,將引發一個ArgumentNullException時:

格式或參數表是空。

如果你正在運行.NET4,請嘗試使用命名參數:

String.Format("Another exception occured: {0}", arg0: null); 

爲什麼擊中params object[]超載?可能是因爲null不是對象,而params的工作方式是可以通過或者將每個值作爲調用中的新對象傳遞給它一個值的數組。也就是說,以下是one in the same

String.Format("Hello, {0}! Today is {1}.", "World", "Sunny"); 
String.Format("Hello, {0}! Today is {1}.", new Object[]{ "World", "Sunny" }) 

所以它轉換沿的線條與你的聲明呼籲一句:

String format = "Another exception occured: {0}"; 
Object[] args = null; 
String.Format(format, args); // throw new ArgumentNullException(); 
+0

另請參見:嘗試'string.Format(「發生:{0}」,(object [])null)'和'string.Format(「發生:{0}」,(object)null)'之間的區別。還有一種可能性:'string.Format(「發生:{0}」,new [] {(object)null,})''。問題只發生在第一種情況下,我猜。 –

8

在你的第一個例子,你打Format(String, Object),看起來喜歡這個時拆解:

public static string Format(string format, object arg0) 
{ 
    return Format(null, format, new object[] { arg0 }); 
} 

注意圍繞這new object[]

第二個,你顯然正在使用Format(string, object[])用法,至少這是我執行相同測試時調用的那個。拆卸,看起來像這樣:

public static string Format(string format, params object[] args) 
{ 
    return Format(null, format, args); 
} 

因此,所有這些實際上得到漏斗來Format(IFormatProvider, string, object[])。酷,讓我們看看那裏的頭幾行:

public static string Format(IFormatProvider provider, string format, params object[] args) 
{ 
    if ((format == null) || (args == null)) 
    { 
     throw new ArgumentNullException((format == null) ? "format" : "args"); 
    } 
... 
} 

...... welp,有你的問題,就在那裏!第一個調用將它包裝在一個新的數組中,所以它不是null。由於調用的Format()的特定實例,明確傳入空值不會這樣做。

2

第一個調用作爲對Format(object)的調用得到解決,而第二個調用作爲對Format(object [])的調用得到解決。這些不同的重載處理空參數的方式不同。

重載分辨率描述爲here。相關部分是對Format的第二次調用,格式(params object [])的重載擴展到格式(object []),該格式優先於格式(對象)。字面null既是一個對象[]也是一個對象,但對象[]更具體,因此被選中。

-3

有兩個差異被以下:

  1. 此處,空值被分配。

    Exception e = null; 
    string msgOne = string.Format("An exception occurred: {0}", e); 
    
  2. 這裏,空值不能以字符串格式讀取,這意味着類型轉換錯誤。

    string msgTwo = string.Format("Another exception occurred: {0}", null); 
    

我給大家簡單的例子: 在這裏,您無法讀取NULL值作爲字符串格式。

string str = null.toString();