ToCharArray和ToArray之间的区别

ToCharArrayToArray什么区别

 string mystring = "abcdef"; char[] items1 = mystring.ToCharArray(); char[] items2 = mystring.ToArray(); 

结果似乎是一样的。

string.ToCharArray()是字符串类的成员。

string.ToArray()实际上使用了IEnumerableToArray()扩展 ,利用了string实现IEnumerable的事实。

在这两者中, string.ToCharArray()可能更具性能。

从C#参考源, string.ToCharArray()的实现是:

 unsafe public char[] ToCharArray() { // < int length = Length; char[] chars = new char[length]; if (length > 0) { fixed (char* src = &this.m_firstChar) fixed (char* dest = chars) { wstrcpy(dest, src, length); } } return chars; } 

同样来自C#参考源, IEnumerable.ToArray()是:

 public static TSource[] ToArray(this IEnumerable source) { if (source == null) throw Error.ArgumentNull("source"); return new Buffer(source).ToArray(); } ... struct Buffer { internal TElement[] items; internal int count; internal Buffer(IEnumerable source) { TElement[] items = null; int count = 0; ICollection collection = source as ICollection; if (collection != null) { count = collection.Count; if (count > 0) { items = new TElement[count]; collection.CopyTo(items, 0); } } else { foreach (TElement item in source) { if (items == null) { items = new TElement[4]; } else if (items.Length == count) { TElement[] newItems = new TElement[checked(count * 2)]; Array.Copy(items, 0, newItems, 0, count); items = newItems; } items[count] = item; count++; } } this.items = items; this.count = count; } internal TElement[] ToArray() { if (count == 0) return new TElement[0]; if (items.Length == count) return items; TElement[] result = new TElement[count]; Array.Copy(items, 0, result, 0, count); return result; } } 

正如你所看到的那样,这更复杂了!

为什么IEnumerable.ToArray()使用优化路径?

还有一件事我们需要解释。

如果你检查Buffer的实现,你会看到这个优化:

 ICollection collection = source as ICollection; if (collection != null) { count = collection.Count; if (count > 0) { items = new TElement[count]; collection.CopyTo(items, 0); } } 

你可以合理地问为什么不采取这条道路? 如果是,这将是string.ToArray()一个很好的优化。

嗯,答案很简单: string不实现ICollection ,因此source as ICollection将返回null,并且不会进行优化。

更糟糕的是,通过Buffer的非优化路径将使用string枚举器,其实现如下:

 public sealed class CharEnumerator : IEnumerator, ICloneable, IEnumerator, IDisposable { private String str; private int index; private char currentElement; internal CharEnumerator(String str) { Contract.Requires(str != null); this.str = str; this.index = -1; } public Object Clone() { return MemberwiseClone(); } public bool MoveNext() { if (index < (str.Length-1)) { index++; currentElement = str[index]; return true; } else index = str.Length; return false; } public void Dispose() { if (str != null) index = str.Length; str = null; } ///  Object IEnumerator.Current { get { if (index == -1) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); if (index >= str.Length) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); return currentElement; } } public char Current { get { if (index == -1) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted)); if (index >= str.Length) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded)); return currentElement; } } public void Reset() { currentElement = (char)0; index = -1; } } ICollection collection = source as ICollection; if (collection != null) { count = collection.Count; if (count > 0) { items = new TElement[count]; collection.CopyTo(items, 0); } } 

这引入了另一个低效率水平。

这个故事的寓意

永远不要使用IEnumerable.ToArray()而不是string.ToCharArray()

ToCharArray方法:

ToCharArray方法将字符串中的字符提取到字符数组中。 然后它显示原始字符串和数组中的元素。

 using System; public class Example { public static void Main() { String s = "AaBbCcDd"; var chars = s.ToCharArray(); Console.WriteLine("Original string: {0}", s); Console.WriteLine("Character array:"); for (int ctr = 0; ctr < chars.Length; ctr++) Console.WriteLine(" {0}: {1}", ctr, chars[ctr]); } } 

ToArray方法:

作用于范围的List类的ToArray方法。

 using System; using System.Collections.Generic; public class Example { public static void Main() { string[] input = { "Brachiosaurus", "Amargasaurus", "Mamenchisaurus" }; List dinosaurs = new List(input); Console.WriteLine("\nCapacity: {0}", dinosaurs.Capacity); Console.WriteLine(); foreach( string dinosaur in dinosaurs ) { Console.WriteLine(dinosaur); } Console.WriteLine("\nAddRange(dinosaurs)"); dinosaurs.AddRange(dinosaurs); Console.WriteLine(); foreach( string dinosaur in dinosaurs ) { Console.WriteLine(dinosaur); } Console.WriteLine("\nRemoveRange(2, 2)"); dinosaurs.RemoveRange(2, 2); Console.WriteLine(); foreach( string dinosaur in dinosaurs ) { Console.WriteLine(dinosaur); } input = new string[] { "Tyrannosaurus", "Deinonychus", "Velociraptor"}; Console.WriteLine("\nInsertRange(3, input)"); dinosaurs.InsertRange(3, input); Console.WriteLine(); foreach( string dinosaur in dinosaurs ) { Console.WriteLine(dinosaur); } Console.WriteLine("\noutput = dinosaurs.GetRange(2, 3).ToArray()"); string[] output = dinosaurs.GetRange(2, 3).ToArray(); Console.WriteLine(); foreach( string dinosaur in output ) { Console.WriteLine(dinosaur); } } } 

如果我们谈论将字符串转换为字母,ToCharArray()函数比ToArray()更快