string.Join需要取一个数组而不是IEnumerable的原因是什么?

正如标题所说:为什么string.Join需要采用数组而不是IEnumerable? 这让我很烦,因为当我需要从LINQ表达式的结果创建一个连接字符串时,我必须添加一个.ToArray()。

我的经验告诉我,我在这里遗漏了一些明显的东西。

升级到.NET 4.0并使用接受IEnumerable的重载 。 否则,只是接受这是一个长期未解决的问题,直到.NET 4.0才解决。 您也可以通过创建自己的扩展方法来解决问题!

 public static class StringEnumerableExtensions { public static string Join(this IEnumerable strings, string separator) { return String.Join(separator, strings.ToArray()); } } 

用法:

 IEnumerable strings; Console.WriteLine(strings.Join(", ")); 

在.NET 4中引入了带有IEnumerable参数的Join重载 – 如果您不使用.NET 4,那么我担心您会因为传递数组或编写自己的实现而陷入困境。

我猜测的原因很简单,当框架首次设计时,它被认为不够重要。 随着LINQ的引入, IEnumerable变得更加突出。

(当然,.NET在设计时没有generics类型,但是没有理由说如果他们认为值得的话,他们就不能用普通的非通用IEnumerable来完成它。)

如果您觉得自己需要它并且无法升级到.NET 4,那么就没有理由不能使用IEnumerable推出自己的Join版本。

它不再了。 .NET 4添加了一些重载以使其更易于使用。 特别是,您不仅不需要传入数组 – 它也不需要是字符串序列。 String.Join(String, IEnumerable)将在序列中的每个项目上调用ToString

如果您没有使用.NET 4但是正在执行许多字符串连接操作,那么您当然可以编写自己的方法。

我猜想String.Join需要能够遍历数组两次(一次测量长度,一次进行复制)。 一些实现iEnumerable的类可以成功地通过一次传递来计算长度,在枚举器上调用Reset,并使用第二次传递来复制数据,但是因为iEnumerable既不支持Capabilities属性也不支持一个族像iMultiPassEnumerable这样的派生类,String.Join可以安全地接受iEnumerable的唯一方法是:(1)枚举某种类型的列表并运行连接,(2)猜测目标字符串大小,并重新分配为需要,或(3)组合这些方法,将短字符串分组为最多8K的簇,然后将所有簇组合成最终结果(这将是预连接簇和来自原始arrays的长串的混合)。

虽然我当然会认为String.Join包含一个将iEnumerable转换为List的开销会很方便,但我没有看到它提供的效率比手动进行这样的转换(不像String的数组版本) .Join,比单独手动连接字符串更有效)。