我遇到的代码类似于以下内容:
var a = (new string [] {}) + string.Empty;
我想问一下:
答案 0 :(得分:6)
.NET Framework中有3个+
运算符重载。
来自C#Spec $7.8.4 Addition operator
string operator + (string x, string y);
string operator + (string x, object y);
string operator + (object x, string y);
这就是你的var a = (new string [] {}) + string.Empty;
匹配第三次重载的原因。
+ (object x, string y)
使用String.Concat(object, object)
重载,implemented喜欢;
public static String Concat(Object arg0, Object arg1)
{
if (arg0 == null)
{
arg0 = String.Empty;
}
if (arg1==null) {
arg1 = String.Empty;
}
return Concat(arg0.ToString(), arg1.ToString());
}
由于new string [] {}
不是null
,因为在MSIL中,它使用newarr
及其文档;
堆栈过渡行为按顺序排列:
- 数组中的元素数量被压入堆栈。
- 从堆栈中弹出元素数量并创建数组。
- 对新阵列的对象引用将被压入堆栈。
醇>
这就是它最后使用object.ToString()
方法的原因。
来自它的文档;
ToString是.NET Framework中的主要格式化方法。它 将对象转换为其字符串表示形式,以使其适合 显示。 ToString方法的默认实现返回完全 类型的限定名称
因此,您的a
将为System.String[]
。
答案 1 :(得分:4)
C#语言规范有一个重载
string operator +(object x, string y)
通过调用x.ToString()
(如果x
不为空,否则只使用""
)并将其与y
连接起来。
因此,您的代码应与
生成相同的代码string a = string.Concat((new string[] {}).ToString(), string.Empty);
所以现在的问题是如何在ToString()
类型上实施string[]
。事实证明,它不会从object
的实现中被覆盖。
答案 2 :(得分:2)
它编译是因为+
运算符将调用string[].ToString
object.ToString
,它返回类型的名称。所以没有意义的结果是"System.String[]"
:
string[] abc = { "a", "b", "c" };
string a = abc + string.Empty; // --> System.String[]
答案 3 :(得分:1)
var s = (new String[] {"a", "b"}) + " ABD";
它将调用new String[] {"a", "b"}
数组对象上的toString()方法,并将其与字符串“ABD”连接。