我担心这是一个非常愚蠢的问题,但我必须遗漏一些东西.
为什么可能要使用String.Copy(string)?
文档说明了这种方法
使用与指定String相同的值创建String的新实例.
由于字符串在.NET中是不可变的,我不确定使用此方法的好处是什么,正如我所想的那样
string copy = String.Copy(otherString);
出于所有实际目的,似乎会产生与之相同的结果
string copy = otherString;
也就是说,除了正在进行的任何内部簿记,以及副本不是ReferenceEquals
otherString 的事实,没有可观察到的差异 - 字符串是一个不可变的类,其相等性基于值,而不是身份.(感谢@Andrew Hare指出我的原始措辞不够精确,表明我意识到Copy
ing和not 之间存在差异,但是担心缺乏有用的差异.)
当然,当传递null
参数时,Copy会抛出一个ArgumentNullException
,而"new instance"可能会占用更多内存.后者几乎不是一个好处,我不确定无效检查是一个足够大的奖金来保证整个复制方法.
谢谢.
随着String.Copy
你实际上是在分配新的内存,然后复制一个到另一个字符串中的字符; 你得到一个全新的实例,而不是让两个变量都是同一个实例.如果你使用带有非托管代码的字符串直接处理内存位置并且可以改变字符串,这可能很重要.
String.Copy
返回一个新的String
,并没有产生相同的结果
String copy = otherString;
试试这个:
using System; class Program { static void Main() { String test = "test"; String test2 = test; String test3 = String.Copy(test); Console.WriteLine(Object.ReferenceEquals(test, test2)); Console.WriteLine(Object.ReferenceEquals(test, test3)); Console.ReadLine(); } }
当您设置test2 = test
这些引用指向相同时String
.该Copy
函数返回一个新String
引用,该引用具有相同的内容,但作为堆上的不同对象.
编辑:有很多人非常沮丧,我没有回答OP的问题.我相信我确实通过纠正问题本身的错误前提来回答这个问题.这是一个类似的(如果不是过于简化的)问题和答案,希望能说明我的观点:
题:
我观察到我的车有两扇门,每侧有一扇门.我相信无论我使用哪扇门,我都会坐在驾驶座上.另一扇门的目的是什么?
回答:
实际上,如果你使用任何一扇门,你将最终进入驾驶员座位.如果您使用驾驶员侧门,您将最终进入驾驶员座位,如果您使用乘客侧门,您将最终进入乘客座位.
现在在这个例子中你可以说答案不是真正的答案,因为问题是"乘客侧门的目的是什么?".但是,由于这个问题完全是基于对门如何运作的误解而不是因为前提的反驳会通过演绎来揭示另一扇门的目的?
这是拼图的一部分.它没有解释你为什么要这样做,但它确实有助于解释功能差异.
如果使用fixed
关键字固定字符串,则内容将是可变的.在我的头脑中,我想不出你想要做到这一点的情况,但这是可能的.
string original = "Hello World"; string refCopy = original; string deepCopy = String.Copy(original); fixed(char* pStr = original) { *pStr = 'J'; } Console.WriteLine(original); Console.WriteLine(refCopy); Console.WriteLine(deepCopy);
输出:
Jello World Jello World Hello World
快速搜索BCL for .NET 4.0显示该string.Copy
方法在大约六个地方被调用.用法大致分为以下几类:
对于可能损坏传入其中的字符串的本机函数的互操作.如果您不能影响P/Invoke声明并且无法修复被调用的函数,string.Copy
则是最佳选择.
对于出于性能原因而就地修改字符串的情况.如果你需要在一个可能很长的字符串中只将几个字符转换为小写,那么在不复制字符串两次并创建额外垃圾的情况下这样做的唯一方法就是改变它.
在似乎没有必要的地方.一些程序员很可能更习惯于Java或C++字符串,并且没有意识到在C#中复制字符串很少有用.
string a = "abc"; string b = String.Copy(a); Monitor.Enter(a); // not the same as Monitor.Enter(b);
然而
string c = "123"; string d = c; Monitor.Enter(c); // the same as Monitor.Enter(d);
至于任何人都会关心的方式,我认为这是完整的.
也
StringBuilder sb = new StringBuilder(100); sb.Append("abc"); string a = sb.ToString(); string b = String.Copy(a);
我认为a
将占用更多的RAM b
,因为a
指向StringBuilder
创建的大小为100的缓冲区.(看StringBuilder.ToString()
方法的内部)
我认为StringBuilder
利用String.Copy()
并成为.NET框架的一部分StringBuilder
确实会改变内容string
.所以a string
并不总是不可改变的.