自动.ToString()?

Afs*_*bbi 3 .net c# interface tostring

我有一个这样的方法:void m1(string str)并有一个这样的类:

public class MyClass
{
    public bool b1 { set; get; }

    //and other properties
}
Run Code Online (Sandbox Code Playgroud)

现在为什么下面的代码不会导致编译错误?

IClass2 _class2 = new Class2();
MyClass c1 = new MyClass();
_class2.m1("abcdef" + c1);
Run Code Online (Sandbox Code Playgroud)

当我调试它时,我意识到c1.ToString()已经传递给了m1.为什么会.ToString()发生这种自动?我唯一可以说的是m1已经在IClass2接口中定义并且已经实现了Class2.

Jon*_*eet 8

这遵循围绕字符串连接的C#语言规范的规则.参见C#4规范的第7.8.4节(加法运算符)

字符串连接:

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
Run Code Online (Sandbox Code Playgroud)

二元+运算符的这些重载执行字符串连接.如果字符串连接的操作数是null,则替换空字符串.否则,通过调用ToString从类型object继承的虚方法,将任何非字符串参数转换为其字符串表示形式.如果ToString返回null,则替换空字符串.

如果您没想到会发生这种情况,请问您对"abcdef" + c1表达结果的期望是什么?

请注意m1,IClass2并且Class2与这里发生的事情无关 - 它只是真正相关的连接表达式:触发调用的ToString()是什么,无论后来发生在字符串中的是什么.


Ani*_*Ani 6

编译器变成"abcdef" + c1了一个string.Concat(object,object)调用.这反过来将调用.ToString()每个参数并连接它们.这是反射器的代码:

public static string Concat(object arg0, object arg1)
{
   if(arg0 == null) arg0 = Empty;
   if(arg1 == null) arg1 = Empty;

   return (arg0.ToString() + arg1.ToString());
}
Run Code Online (Sandbox Code Playgroud)

请注意,最后一行涉及string.Concat(string, string)实际连接发生的位置的调用.