2012-09-18 185 views
-2

我只注意到這個MessgeBox.Show()內的ToString()方法的工作太:爲什麼我不需要

MessageBox.Show("number of things in the report are " + myHashSetVariable.Count); 

我,我應該使用myHashSetVariable.Count.ToString的印象()

這是VS2010中某種編譯器/解釋器的改進嗎?我使用VS2010臨

+3

'ToString'被隱式調用,因爲第一個運算符是一個字符串類型。 – zzzzBov

+1

並且與您的開發環境版本無關。 – Adam

+1

[自動.ToString()?](http://stackoverflow.com/questions/3759343/automatic-tostring)也可能重複[字符串=字符串+ int:場景背後是什麼?](http:// stackoverflow。 com/questions/3398604/string-string-int-whats-behind-the-scene-c) –

回答

5

首先,這的與MessageBox.Show無關。這與+運營商有關。字符串+對象的結果等於一個字符串。

該語言中的+運算符有許多重載(您也可以爲用戶定義的類型添加自己的屬性)。只有兩個以object作爲參數,即operator+(string, object)operator+(object, string)。在這兩種情況下,運營商實施的主體將在object參數上調用ToString,然後使用string.Concat產生結果。

由於您的變量是一個整數,它使用operator+string作爲第一個參數,它將匹配operator+(string, object)一個沒有其他候選人。

+1

除了按照Jon Skeet的說法,''''''''''''''''''('''''')不能重載(http://stackoverflow.com/a/1788234/1106367)。相反,'+'*編譯爲'string.Concat' *。 – Adam

+0

@codesparkle是的,對於用戶定義的類型,「+」運算符的處理方式與針對少數本地類型(如「字符串」)的處理方式不同。雖然在解決特定的重載後會發生什麼,但它仍然會使用相同的方法解析規則來確定要調用哪個「operator +」的重載。 – Servy

2

的ToString被隱式調用驗證,你可以省略字符串的郵件中的文字,現在,你將需要顯式調用的ToString擺脫編譯錯誤

MessageBox.Show(myHashSetVariable.Count); //This gives the error 
+0

@pst好吧,對於初學者來說,大部分帖子都是在我的評論後重新編寫的,所以我已經刪除了它。接下來,正如我在回答中所說的那樣,「MessageBox.Show」與此行爲毫無關係。它與'+'運算符有關。 – Servy

1

你可以做同樣的事情是這樣的:

int intval = 5; 
string blah = "This is my string" + intval; 

ToString()被稱爲隱含在那裏。儘管如此,我覺得明確地調用它是有道理的,以使代碼更清晰。

1

塞維的說得沒錯。以下是一些鏈接和示例,可幫助您進一步理解字符串連接和隱式轉換的主題。

C#語言指定部7.7.4 Addition operator狀態:

當一個或兩個 操作數的類型字符串的二進制+運算符執行字符串連接。 [...]任何非字符串參數是 通過調用從對象類型繼承的虛擬 ToString方法轉換爲其字符串表示形式。

爲了您的INT預定義類型的簡單的情況下,你按照規範眼看int.ToString()調用。但是如果你有一個用戶定義的類型,你可能會遇到implicit轉換爲字符串(在6.4.3 User-defined implicit conversions中的細節)。

要進行實驗,請定義一個模仿MessageBox.Show(string)的方法。

static void Write(string s) 
{ 
    Console.WriteLine(s); 
} 

而一些用戶定義的類:

首先,一個空的類沒有覆蓋,或者它不是直接調用Console.WriteLine,因爲它提供了寫的許多重載,包括寫(Int32)已是非常重要的轉換。

class EmptyClass { 
} 

和一個覆蓋Object.ToString的類。

class ToStringOnly { 
    public override string ToString() { 
     return "ToStringOnly"; 
    } 
} 

這表明了隱式轉換爲字符串另一類:

class ImplicitConversion { 
    static public implicit operator string(ImplicitConversion b) { 
     return "Implicit"; 
    } 
} 

最後,我不知道,當一個類都定義了一個隱式轉換重寫Object.ToString會發生什麼:

class ImplicitConversionAndToString { 
    static public implicit operator string(ImplicitConversionAndToString b) { 
     return "Implicit"; 
    } 
    public override string ToString() { 
     return "ToString"; 
    } 
} 

隱式轉換測試:

// Simple string, okay 
Write("JustAString"); // JustAString 

// Error: cannot convert from 'int' to 'string' 
//Write(2); 

// EmptyClass cannot be converted to string implicitly, 
// so we have to call ToString ourselves. In this case 
// EmptyClass does not override ToString, so the base class 
// Object.ToString is invoked 
//Write(new EmptyClass()); // Error 
Write(new EmptyClass().ToString()); // StackOverflowCSharp.Program+EmptyClass 

// implicit conversion of a user-defined class to string 
Write(new ImplicitConversion()); // Implicit 

// while ToStringOnly overrides ToString, it cannot be 
// implicitly converted to string, so we have to again 
// call ToString ourselves. This time, however, ToStringOnly 
// does override ToString, and we get the user-defined text 
// instead of the type information provided by Object.ToString 
//Write(new ToStringOnly()); // ERROR 
Write(new ToStringOnly().ToString()); // "ToStringOnly" 

而且,更相關的,用於字符串連接一個試驗:

// Simple string 
Write("string"); // "string" 

// binary operator with int on the right 
Write("x " + 2); // "x 2" 

// binary operator with int on the left 
Write(3 + " x"); // "3 x" 

// per the specification, calls Object.ToString 
Write("4 " + new EmptyClass()); // "4 StackOverflowCSharp.Program+EmptyClass" 

// the implicit conversion has higher precedence than Object.ToString 
Write("5 " + new ImplicitConversion()); // "5 Implicit" 

// when no implicit conversion is present, ToString is called, which 
// in this case is overridden by ToStringOnly 
Write("6 " + new ToStringOnly()); // "6 ToStringOnly" 

並與一類既定義了一個隱式轉換重寫Object.ToString(),以密封它全部:

// In both cases, the implicit conversion is chosen 
Write(new ImplicitConversionAndToString()); // "Implicit" 
Write("8: " + new ImplicitConversionAndToString()); // 8: Implicit