Servy 做对了。以下是一些链接和示例,可能有助于您进一步理解字符串连接和隐式转换的主题。
C# 语言规范部分7.7.4 Addition operator 声明:
二元 + 运算符在一个或两个时执行字符串连接
操作数是字符串类型。 [...] 任何非字符串参数都是
通过调用 virtual 转换为其字符串表示形式
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