C# - как создать массив из перечислителя

В C#, каков самый элегантный способ создания массива объектов из перечислителя объектов? например, в этом случае у меня есть перечислитель, который может возвращать байты, поэтому я хочу преобразовать это в byte[].

EDIT: код, который создает перечислитель:

IEnumerator<byte> enumerator = updDnsPacket.GetEnumerator();

3 ответов


предполагая, что у вас есть IEnumerable можно использовать перечисли.Метод toArray метод расширения:

IEnumerable<byte> udpDnsPacket = /*...*/;

byte[] result = udpDnsPacket.ToArray();

хорошо, предположим, что у вас есть фактический перечислитель (IEnumerator<byte>), вы можете использовать цикл while:

var list = new List<byte>();
while(enumerator.MoveNext())
  list.Add(enumerator.Current);
var array = list.ToArray();

на самом деле, я бы предпочел повернуть IEnumerator<T> до IEnumerable<T>:

public static class EnumeratorExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this IEnumerator<T> enumerator)
    {
      while(enumerator.MoveNext())
          yield return enumerator.Current;
    }
}

затем вы можете получите массив:

var array = enumerator.ToEnumerable().ToArray();

конечно, все это предполагает, что вы используете .Net 3.5 или выше.


так как у вас есть IEnumerator<byte>, а не IEnumerable<byte>, вы не можете использовать LINQ-это ToArray метод. ToArray - это метод расширения on IEnumerable<T>, а не IEnumerator<T>.

Я бы предложил написать метод расширения, подобный Enumerable.ToArray но тогда с целью создания массива вашего перечислителя:

public T[] ToArray<T>(this IEnumerator<T> source)
{
    T[] array = null;
    int length = 0;
    T t;
    while (source.MoveNext())
    {
        t = source.Current();
        if (array == null)
        {
            array = new T[4];
        }
        else if (array.Length == length)
        {
            T[] destinationArray = new T[length * 2];
            Array.Copy(array, 0, destinationArray, 0, length);
            array = destinationArray;
        }
        array[length] = t;
        length++;
    }
    if (array.Length == length)
    {
        return array;
    }
    T[] destinationArray = new T[length];
    Array.Copy(array, 0, destinationArray, 0, length);
    return destinationArray;
}

происходит то, что вы перебираете элемент перечислителя по элементам и добавляете их в массив, который постепенно увеличивается в размерах.