Roy*_*mir 24 c# string concatenation .net-4.0
我在调查String.Concat :(反射器)

很奇怪 :
有值数组,
他们创造了一个新的阵列,以后他们会把他送到ConcatArray.
题 :
为什么他们创建了一个新阵列?他们values从一开始......
代码:
public static string Concat(params string[] values)
{
if (values == null)
{
throw new ArgumentNullException("values");
}
int totalLength = 0;
string[] strArray = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
string str = values[i];
strArray[i] = (str == null) ? Empty : str;
totalLength += strArray[i].Length;
if (totalLength < 0)
{
throw new OutOfMemoryException();
}
}
return ConcatArray(strArray, totalLength);
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 34
好吧,有一点,它意味着新数组的内容可以被信任为非null ....并且不变.
如果没有复制,另一个线程可以在调用期间修改原始数组ConcatArray,这可能会引发异常甚至触发安全漏洞.通过复制,可以随时更改输入数组 - 每个元素只读取一次,因此不会出现不一致.(结果可能是旧元素和新元素的混合,但最终不会导致内存损坏.)
假设ConcatArray被信任从它传递的数组中的字符串中进行批量复制,而不检查缓冲区溢出.然后,如果您在恰当的时间更改输入数组,则可能最终在分配的内存之外写入.不良.使用这个防御性副本,系统可以确定1总长度确实是总长度.
1好吧,除非使用反射来改变字符串的内容.但是如果没有相当高的权限就无法做到这一点 - 而改变数组的内容很容易.
Eri*_*ert 16
他们为什么要创建一个新阵列?
我可以证实乔恩的推测; 我在我面前有原始的源代码.评论表明复制的原因是因为一些愚蠢的人可能会改变在另一个线程上传入的数组.然后会发生什么?长度的计算可以说结果中将有一百个字节的字符串数据,但是到复制发生的时候,数组中可能有一百万字节的字符串数据.
那会很糟糕.通过复制可以轻松防止问题.