2012-09-18 189 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