Создать разделенные запятыми строки C #? - PullRequest
42 голосов
/ 03 февраля 2011

У меня есть объект, который содержит много значений, некоторые из которых (не все значения из объекта) необходимо поместить в строку csv. Мой подход был такой:

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

Почему-то я думаю, что есть лучший, более элегантный способ?

Ответы [ 5 ]

94 голосов
/ 03 февраля 2011

Если вы поместите все свои значения в массив, по крайней мере, вы можете использовать string.Join.

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

Вы также можете использовать перегрузку string.Join, которая принимает params string в качестве второго параметра, подобного этому:

string csvString = string.Join(",", value1, value2, value3, ...);
10 голосов
/ 03 февраля 2011

Другой подход заключается в использовании класса CommaDelimitedStringCollection из пространства имен / сборки System.Configuration.Он ведет себя как список, плюс у него есть переопределенный метод ToString, который возвращает строку через запятую.

Плюсы - более гибкий, чем массив.

Минусы - вы не можете передать строку, содержащуюзапятая.

CommaDelimitedStringCollection list = new CommaDelimitedStringCollection();

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

string s = list.ToString(); //Huey,Dewey,Louie
3 голосов
/ 03 февраля 2011

Вы можете использовать метод string.Join, чтобы сделать что-то вроде string.Join(",", o.Number, o.Id, o.whatever, ...).

edit: Как говорит digEmAll, string.Join работает быстрее, чем StringBuilder. Они используют внешнюю реализацию для строки. 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 за подсказку.

2 голосов
/ 03 февраля 2011

Если вы используете .Net 4, вы можете использовать перегрузку для string.Join, которая принимает IEnumerable, если у вас их тоже есть в списке:

string.Join(", ", strings);
1 голос
/ 03 февраля 2011

Вы можете переопределить метод ToString () вашего объекта:

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