代码之家  ›  专栏  ›  技术社区  ›  sbi

字符串的原因是什么。Join需要使用数组而不是IEnumerable?

c#
  •  10
  • sbi  · 技术社区  · 14 年前

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

    我的经验告诉我,我遗漏了一些显而易见的东西。

    4 回复  |  直到 14 年前
        1
  •  9
  •   jason    14 年前

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

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

    用法:

    IEnumerable<string> strings;
    Console.WriteLine(strings.Join(", "));
    
        2
  •  8
  •   LukeH    14 年前

    Overloads of Join that take an IEnumerable<T> argument 是在.NET 4中引入的—如果您不使用.net4,那么恐怕您将不得不传递数组或编写自己的实现。

    我想原因很简单,就是在最初设计框架时,它被认为不够重要。 IEnumerable<T> 随着LINQ的引入变得更加突出。

    (当然,.NET在设计时没有泛型类型,但是没有理由不使用普通的非泛型类型 IEnumerable 如果他们认为值得的话。)

    你没有理由不把你自己的版本 加入 IEnumerable<T> 如果你觉得你需要它,你不能升级到.NET 4。

        3
  •  3
  •   Jon Skeet    14 年前

    some overloads 以便于使用。特别是,不仅不需要传入数组,而且也不需要是字符串序列。 String.Join(String, IEnumerable<T>) 将调用 ToString

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

        4
  •  0
  •   supercat    14 年前

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

    虽然我肯定会承认它对于String.Join来说是很方便的,但是我不认为它提供的效率比手动进行这种转换更高(与String.Join的数组版本不同,后者比单独手动连接字符串更有效)。