将IEnumerable<T>转换为T[]的最佳方法

8

如何将通用的 IEnumerable<T> 实现转换为 T 类型的数组?目前我有如下解决方案:

IEnumerable<string> foo = getFoo();
string[] bar = new List<string>(foo).ToArray();

通过 List<T> 进行传输似乎是不必要的,但我还没有找到更好的方法。

注意:这里我正在使用 C# 2.0。


在3.5中,你可以使用getFoo().ToArray(),但这对你并没有太大帮助 :) - Eric Schoonover
4个回答

15

.NET 3.0及以上版本:

IEnumerable<T>上调用ToArray扩展方法,它执行类型嗅探和其他一些优化,实现几乎与下面相同的功能。

.NET 2.0及之前版本:

通常来说,使用一个List<T>,并用IEnumerable<T>初始化它,然后调用ToArray可能是最简单的方法。

List<T>构造函数会检查IEnumerable<T>是否实现了ICollection<T>以获取项目计数,以正确初始化列表容量。如果没有,则会像平常一样进行扩展。

当然,您可能会因为将IEnumerable<T>转换为T[]而创建许多List<T>实例。为此,您可以编写自己的方法,但实际上只是重复了已经存在于List<T>中的代码。


1
如果您有来自另一个源的计数,而不是从IEnumerable<>的其他接口(如ICollection)获取计数,则应使用您的计数自己创建数组。通过列表传递可能是最好的方式。 - configurator

5

通过使用.NET Reflector,看起来Linq ToArray扩展方法基本上与将IEnumerable传递到List<>中做的事情相同。Buffer类是一个内部类,但其行为似乎非常类似于List<>。

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

1
// src is IEnumerable<T>
// target is T[]
target = src == null ? new T[] {} : src.ToArray();

0
如果无法确定数组的长度,那么这是最好的方法。
IEnumerable 中没有任何方法可以确定长度,但也许您的代码有其他方法来找到长度。如果有,请使用该方法构建一个数组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接