gpt4 book ai didi

c# - ToCharArray 和 ToArray 之间的区别

转载 作者:IT王子 更新时间:2023-10-29 04:52:24 28 4
gpt4 key购买 nike

ToCharArrayToArray 有什么区别

string mystring = "abcdef";

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

结果好像是一样的

最佳答案

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

string.ToArray()实际上正在使用 a ToArray() extension of IEnumerable<T> , 利用 string工具 IEnumerable<char> .

两者中,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<T>.ToArray() 的实现是:

public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return new Buffer<TSource>(source).ToArray();
}

...

struct Buffer<TElement>
{
internal TElement[] items;
internal int count;

internal Buffer(IEnumerable<TElement> source) {
TElement[] items = null;
int count = 0;
ICollection<TElement> collection = source as ICollection<TElement>;
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<T>.ToArray()使用优化路径?

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

如果您检查 Buffer<T> 的执行情况你会看到这个优化:

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

您可以合理地问为什么不采用该路径?如果是,这将是对 string.ToArray() 的一个很好的优化。 .

嗯,答案很简单:A string没有实现 ICollection<T>因此 source as ICollection<TElement>将返回 null,并且该优化将不会完成。

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

public sealed class CharEnumerator : IEnumerator, ICloneable, IEnumerator<char>, 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;
}

/// <internalonly/>
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<TElement> collection = source as ICollection<TElement>;
if (collection != null) {
count = collection.Count;
if (count > 0) {
items = new TElement[count];
collection.CopyTo(items, 0);
}
}

这带来了另一个层面的低效率。

这个故事的寓意

切勿使用 IEnumerable<char>.ToArray()而不是 string.ToCharArray() !

关于c# - ToCharArray 和 ToArray 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37139053/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com