本文介绍了ToCharArray和ToArray的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是 ToCharArray 的ToArray

string mystring = "abcdef";

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



的结果似乎是相同的。

The result seems to be the same.

推荐答案

是String类的成员。

string.ToCharArray() is a member of the string class.

string.ToArray ()实际使用,采取的事实,即字符串工具的IEnumerable<焦炭方式>

string.ToArray() is actually using a ToArray() extension of IEnumerable<T>, taking advantage of the fact that string implements IEnumerable<char>.

在这两个, string.ToCharArray()很可能是更好的性能。

Of the two, string.ToCharArray() is likely to be more performant.

从C#参考源,<$ C $执行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;
    }
}        



正如你所看到的,这是一个复杂得多!

As you can see, that's a LOT more complicated!

为什么不的IEnumerable< T> .ToArray()使用优化的路径

Why doesn't IEnumerable<T>.ToArray() use the optimised path?

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

There's one other thing we need to explain.

如果您检查的实施缓冲器< T> 你会看到这样的优化:

If you inspect the implementation of Buffer<T> you'll see this optimisation:

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()

You could reasonably ask why that path isn't taken? If it was, this would be a good optimisation for string.ToArray().

那么,答案是一个很好的优化简单地说:A 字符串不执行的ICollection< T> ,因此源作为的ICollection< TElement方式> 将返回null,并且优化将无法完成

Well, the answer is simply: A string doesn't implement ICollection<T> and therefore source as ICollection<TElement> will return null, and that optimisation will not be done.

更糟糕的是,通过非优化的路径缓冲器< T> 将使用字符串枚举,其实现如下:

Even worse, the non-optimised path through Buffer<T> will use the string enumerator, which is implemented as follows:

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);
    }
}    

这引入了低效率的完全是另外一个层次。

This introduces a whole other level of inefficiency.

这个故事的寓意

不要使用的IEnumerable<焦炭> .ToArray()而不是 string.ToCharArray()

这篇关于ToCharArray和ToArray的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 10:55