为什么我不需要在MessgeBox.Show()中关闭ToString()方法

我刚才注意到这个也有效:

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

我的印象是我应该使用myHashSetVariable.Count.ToString()

它是VS2010中的某种编译器/解释器改进吗? 我正在使用VS2010 Pro

首先,这与MessageBox.Show无关。 这与+运算符有关。 string + object的结果等于一个字符串。

语言中的+运算符有许多重载(您也可以为用户定义的类型添加自己的重载)。 只有两个将object作为参数,即operator+(string, object)operator+(object, string) 。 在这两种情况下,运算符实现的主体都会在object参数上调用ToString ,然后使用string.Concat来生成结果。

由于你的变量是一个整数,它使用operator+ with string作为第一个参数,它将匹配operator+(string, object) ,而不是其他候选者。

隐式调用ToString来validation你可以省略消息中的字符串文字,现在你需要显式调用ToString来摆脱编译错误

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

你可以用这种方式做同样的事情:

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

在那里隐式调用ToString() 。 虽然,我发现明确地调用它是有意义的,以使代码更清晰。

Servy的说得对。 以下是一些链接和示例,可能有助于您进一步理解字符串连接和隐式转换的主题。

C#语言规范部分7.7.4添加运算符状态:

当一个或两个操作数的类型为字符串时,binary +运算符执行字符串连接。 […]通过调用从类型对象inheritance的虚拟ToString方法,将任何非字符串参数转换为其字符串表示forms。

对于int预定义类型的简单情况,您将看到根据规范调用int.ToString() 。 但是如果你有一个用户定义的类型,你也可能会遇到隐式转换为字符串( 6.4.3用户定义的隐式转换中的血腥细节)。

要进行实验,请定义一个模仿MessageBox.Show(string)的方法。 重要的是不要直接调用Console.WriteLine ,因为它提供了大量的Write重载,包括Write(Int32):

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

以及一些用户定义的类:

首先,没有覆盖或转换的空类。

 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