【问题标题】:Create a comma-separated strings in C#在 C# 中创建逗号分隔的字符串
【发布时间】:2011-06-20 12:31:03
【问题描述】:

我有一个包含许多值的对象,其中一些(不是对象中的所有值)需要放入CSV 字符串中。我的做法是这样的:

string csvString = o.number + "," + o.id + "," + o.whatever ....

有没有更好、更优雅的方式?

【问题讨论】:

  • 一般来说,使用+ 符号连接字符串被认为效率较低。它会创建更多要被垃圾收集的对象。

标签: c# string-concatenation


【解决方案1】:

如果将所有值放在一个数组中,至少可以使用string.Join

string[] myValues = new string[] { ... };
string csvString = string.Join(",", myValues);

您还可以使用string.Join 的重载,它将params string 作为第二个参数,如下所示:

string csvString = string.Join(",", value1, value2, value3, ...);

【讨论】:

  • +1 用于在其中使用一个数组,当有多个“几个”值时,它可以使代码更清晰。
  • @Bazzz - 是的,如果您在 join 方法调用中输入 10 多个参数,它可能会很快变得混乱。我认为第一种方法是最干净的,但是对于一些值,第二种方法也可以。
  • 为什么对这个答案投了两次反对票?一个理由将不胜感激,这样每个人都知道你觉得这个答案有什么问题。
  • @fearofawhackplanet - 感谢您提供理由。这样更有意义;)您当然有权发表自己的意见。我只是喜欢听;)
  • @fear: string.Join 使用参数数组。这意味着直接传递参数的代码将被编译器自动转换为使用数组。就开销而言,调用之间没有区别。
【解决方案2】:

您可以覆盖对象的 ToString() 方法:

public override string ToString ()
{
    return string.Format ("{0},{1},{2}", this.number, this.id, this.whatever);
}

【讨论】:

  • 这仅在他确切知道要放入字符串中的元素数量时才有用。 string.Join 可能更合适。
  • 是的,但是因为他想创建一个 csv 文件,所以每次的元素很可能都是相同的。我不知道,这是一个偏好问题。
  • 我从这个问题中假设他总是想要相同的字段,所以他肯定知道元素的数量。这个答案没有错,尽管我真的不喜欢在这里覆盖 ToString ,因为它可能不够通用。无论如何,我要 +1。
  • @fearofawhackplanet - 没有错。只是偏好问题;)
【解决方案3】:

您可以使用string.Join 方法执行string.Join(",", o.Number, o.Id, o.whatever, ...) 之类的操作。

edit:正如 digEmAll 所说,string.Join 比 StringBuilder 快。他们对 string.Join 使用外部实现。

分析代码(当然在没有调试符号的版本中运行):

class Program
{
    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        string r;
        int iter = 10000;

        string[] values = { "a", "b", "c", "d", "a little bit longer please", "one more time" };

        sw.Restart();
        for (int i = 0; i < iter; i++)
            r = Program.StringJoin(",", values);
        sw.Stop();
        Console.WriteLine("string.Join ({0} times): {1}ms", iter, sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < iter; i++)
            r = Program.StringBuilderAppend(",", values);
        sw.Stop();
        Console.WriteLine("StringBuilder.Append ({0} times): {1}ms", iter, sw.ElapsedMilliseconds);
        Console.ReadLine();
    }

    static string StringJoin(string seperator, params string[] values)
    {
        return string.Join(seperator, values);
    }

    static string StringBuilderAppend(string seperator, params string[] values)
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(values[0]);
        for (int i = 1; i < values.Length; i++)
        {
            builder.Append(seperator);
            builder.Append(values[i]);
        }
        return builder.ToString();
    }
}

string.Join 在我的机器上用了 2 毫秒,而 StringBuilder.Append 用了 5 毫秒。所以有明显的区别。感谢 digAmAll 的提示。

【讨论】:

  • string.JoinStringBuilder 一样快(如果不是稍微快一点的话),因为它们都只分配一个字符串
  • 普通字符串concat(例如使用string1 += string2)的问题是原来的string1被扔掉了(因为strings是不可变的),string1和string2的新和被string1指向,如果重复执行,效率不高。但是,正如 digEmAll 也指出的那样, string.Join 当然只分配一次字符串。数组中的每个元素都不是一次。
  • string.Join 的一个缺点(直到 .NET 4.0)是它需要一个字符串数组,如果你只有一个通用的 IEnumerable&lt;string&gt; 就强制你分配一个字符串...无论如何 .NET 4.0已解决此问题
  • 你说得对,我编辑了我的帖子。但是我想知道 string.Join 调用了哪个外部方法,因为它是本机实现而不是在 mscorlib 中?
  • @digEmAll:但基础仍然是corecct,所以没有必要找借口:-)。 string.Join(string, string[]) 和 string.Join(string, string[], int, int) 重载仍然使用 FastAllocateString,因此可能比 string.Join 的其他重载更快。但我同意 string.Join 的首选用法,而不是使用 StringBuilder 实现自己的 Join-Logic。
【解决方案4】:

如果您使用的是 .NET 4,则可以使用 string.Join 的重载,如果您也将它们放在 List 中,则它需要一个 IEnumerable:

string.Join(", ", strings);

【讨论】:

    【解决方案5】:

    另一种方法是使用 System.Configuration 命名空间/程序集中的 CommaDelimitedStringCollection 类。它的行为类似于一个列表,而且它有一个重写的 ToString 方法,该方法返回一个逗号分隔的字符串。

    优点 - 比数组更灵活。

    缺点 - 您不能传递包含逗号的字符串。

    CommaDelimitedStringCollection list = new CommaDelimitedStringCollection();
    
    list.AddRange(new string[] { "Huey", "Dewey" });
    list.Add("Louie");
    //list.Add(",");
    
    string s = list.ToString(); //Huey,Dewey,Louie
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      相关资源
      最近更新 更多