The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

分享一個會讓人精神錯亂的 .NET 觀念 ( 神奇的 + 運算子 )

C# / .NET 是個完全物件導向的程式語言,所有的物件都有自己的型別(Type),所以瞭解型別與善用型別是開發 .NET 應用程式很重要的基礎。

假設你現在到一間公司面試,面試官問你一個問題:「請問以下程式是否可以正常編譯並執行?」

Console.WriteLine(1 + "1" + true);

我問過 5 個會寫 .NET 的朋友,有 4 個人的回答都一樣:「不可以,因為這三個東西型別都不一樣,所以不可能被編譯,也無法執行」。

但正確答案是:「可以編譯,可以執行,而且執行結果為:11True

我在過年前 Review 同事寫的程式時,發現有一段 Code 他真的是這樣寫,而且還編譯過了,編譯器還沒提供任何警告(warning)訊息,讓我當下精神錯亂,因為我無法解釋這種型別錯亂的狀況,而且這件事竟然會在 C# 中發生。

這讓我不禁想深入探討與研究為何如此,所以我親自寫了一個小程式拿去 C# 編譯器編譯,然後再用 Reflector 反組譯回來,看看實際編譯後的程式碼長的怎樣。

1. 將以下程式碼編譯,但反組譯後��結果一模一樣:

Console.WriteLine(1 + "1" + true);

2. 然後再試試以以下這段:

Console.WriteLine(1 + "1" + true + DateTime.Now);

反組譯的結果就不太一樣了,變成以下程式:

Console.WriteLine(string.Concat(new object[] { 1, "1", true, DateTime.Now }));

3. 然後再試著用兩個 object 進行相加,這次就無法再編譯了:

object i = 1;
object j = "OK";
Console.Write(i + j);

---

接著,我就往 MSDN 聖殿尋找解答,最後真的給我找到關於這點疑問的說明:

The binary + operator performs string concatenation when one or both operands are of type string. If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. If ToString returns null, an empty string is substituted.

由此可知 C# 的加號( + )運算子預設就支援字串串加的功能,只要一群字串串接的物件中只要有一個以上的物件型別是「字串」的話,就會全部變成「字串相加」,只要遇到「非字串」的物件,預設會使用繼承至 object 物件的 ToString() 方法進行轉型,讓所有物件都變成「字串」後進行相加動作。如果物件回傳值為 null 的話,也會改以空字串替代。

我想這一個觀念在未來也許可以拿來當成我面試程式設計師的題目。^^

相關連結