15

在 C# 中,从对象枚举器创建对象数组的最优雅方法是什么?例如,在这种情况下,我有一个可以返回字节的枚举器,所以我想将其转换为字节[]。

编辑:创建枚举器的代码:

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

3 回答 3

28

好的,所以,假设您有一个实际的枚举器 ( 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 或更高版本。

于 2010-08-21T12:53:21.280 回答
5

假设你有一个IEnumerable<T>,你可以使用Enumerable.ToArray扩展方法:

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

byte[] result = udpDnsPacket.ToArray();
于 2010-08-21T12:41:17.753 回答
3

由于您有 anIEnumerator<byte>而不是IEnumerable<byte>,因此您不能使用 Linq 的ToArray方法。ToArray是on的扩展方法IEnumerable<T>,而不是 on 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;
}

发生的情况是您逐项迭代枚举器并将它们添加到大小逐渐增加的数组中。

于 2010-08-21T12:54:26.200 回答