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

时间:2012-09-18 17:33:39

标签: c#

我刚才注意到这也有效:

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

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

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

4 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

你可以这样做:

int intval = 5;
string blah = "This is my string" + intval;
隐含地在那里调用

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

答案 3 :(得分:1)

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

C#语言规范部分7.7.4 Addition operator声明:

  

binary +运算符在一个或两个时执行字符串连接   操作数是字符串类型。 [...]任何非字符串参数是   通过调用虚拟转换为其字符串表示形式   从类型对象继承的ToString方法。

对于int预定义类型的简单情况,您会看到根据规范调用int.ToString()。但是,如果您有用户定义的类型,则可能会遇到implicit转换为字符串(6.4.3 User-defined implicit conversions中的血腥详细信息)。

要进行实验,请定义一个模仿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