ToCharArray和ToArray之间的区别
ToCharArray
和ToArray
什么区别
string mystring = "abcdef"; char[] items1 = mystring.ToCharArray(); char[] items2 = mystring.ToArray();
结果似乎是一样的。
string.ToCharArray()
是字符串类的成员。
string.ToArray()
实际上使用了IEnumerable
的ToArray()
扩展 ,利用了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
是:
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
使用优化路径?
还有一件事我们需要解释。
如果你检查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
而不是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()更快