在C#中用"逗号和逗号"IEnumerable的更好方法

0 c# linq string join

可能重复:
LINQ列表到句子格式(插入逗号&"和")

想象一下这些输入和结果:

[] -> ""

["Hello World!"] -> "Hello World!"

["Apples", "bananas"] -> "Apples, and bananas" (put your grammar books away)

["Lions", "Tigers", "Bears"] -> "Lions, Tigers, and Bears" (oh my!)
Run Code Online (Sandbox Code Playgroud)

现在,想象一下输入都是IEnumerable<string>.有什么好处(哪里好可能包含"小而整齐","易于理解","使用LINQ的全部功能",或其他只要有理由)在C#中编写一个函数来执行此操作?我真的想避免"强制循环"方法.

我目前的方法如下:

string Commaize (IEnumerable<string> list) {
    if (list.Count() > 1) {
        list = list.Take(list.Count() - 2).Concat(
            new[] { list.Reverse().Take(2).Reverse()
                        .Aggregate((a, b) => a + " and " + b) });
    }
    return String.Join(", ", list.ToArray());
}
Run Code Online (Sandbox Code Playgroud)

但它感觉不是很"好".这是针对.NET3.5所以ToArray()这里需要这个位.如果list为null,则结果为UB.

Tho*_*que 7

与其他答案(CodeInChaos发布的答案除外)不同,此实现仅枚举输入序列一次.如果枚举它的成本很高(例如数据库查询,Web服务调用......),这可能很重要.

string Commaize (IEnumerable<string> list)
{
    string previous = null;
    StringBuilder sb = new StringBuilder();
    foreach(string s in list)
    {
        if (previous != null)
            sb.AppendFormat("{0}, ", previous);
        previous = s;
    }
    if (previous != null)
    {
        if (sb.Length > 0)
            sb.AppendFormat("and {0}", previous);
        else
            sb.Append(previous);
    }
    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)