采取以下代码:
public static string ReverseIt(string myString)
{
char[] foo = myString.ToCharArray();
Array.Reverse(foo);
return new string(foo);
}
我明白字符串是不可变的,但我不明白的是为什么需要调用一个新的字符串?
return new string(foo);
而不是
return foo.ToString();
我必须假设它与重新组装 CharArray 有关(但这只是猜测)。
两者之间有什么区别?如何知道何时返回新字符串而不是返回表示当前对象的 System.String?
很简单,因为在 char 数组上调用 ToString() 可以得到
系统.Char[]
尝试
char[] ca = "Hello world".ToCharArray();
Console.WriteLine("{0}", ca);
你不明白
Hello World
另外调用 Array.Reverse 来反转字符串是一个坏主意,Tony 和 Jon 在他们的 - 现在著名的 - 堆栈内存溢出演示中提到过它
第二个只是在 char 数组的实例上调用 ToString,而第一个使用字符串构造函数从 char 数组中获取字符串。他们真的没有任何关系。
这是 2 个函数的 IL:
private string test(String myString){
char[] foo = myString.ToCharArray();
Array.Reverse(foo);
return new string(foo);
}
test:
IL_0000: nop
IL_0001: ldarg.1
IL_0002: callvirt System.String.ToCharArray
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: call System.Array.Reverse
IL_000E: nop
IL_000F: ldloc.0
IL_0010: newobj System.String..ctor
IL_0015: stloc.1
IL_0016: br.s IL_0018
IL_0018: ldloc.1
IL_0019: ret
private string tess(String myString)
{
char[] foo = myString.ToCharArray();
Array.Reverse(foo);
return foo.ToString();
}
tess:
IL_0000: nop
IL_0001: ldarg.1
IL_0002: callvirt System.String.ToCharArray
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: call System.Array.Reverse
IL_000E: nop
IL_000F: ldloc.0
IL_0010: callvirt System.Object.ToString
IL_0015: stloc.1
IL_0016: br.s IL_0018
IL_0018: ldloc.1
IL_0019: ret
字符数组在字符串构造函数中对 CLR 进行更快速/优化的外部调用,因此在本例中,这是一个更快的操作。
String
为此有一个特定的构造函数:
[MethodImpl(MethodImplOptions.InternalCall)]
public extern String(char[] value);