web-dev-qa-db-fra.com

Créer des chaînes séparées par des virgules C #?

J'ai un objet qui contient de nombreuses valeurs, certaines d'entre elles (pas toutes les valeurs de l'objet) doivent être mises dans une chaîne csv. Mon approche était la suivante:

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

D'une certaine manière, je pense qu'il y a une meilleure façon, plus élégante?

43
grady

Si vous mettez toutes vos valeurs dans un tableau, vous pouvez au moins utiliser string.Join.

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

Vous pouvez également utiliser la surcharge de string.Join qui prend params string comme deuxième paramètre comme celui-ci:

string csvString = string.Join(",", value1, value2, value3, ...);
97
Øyvind Bråthen

Une autre approche consiste à utiliser la classe CommaDelimitedStringCollection de l'espace de noms/Assembly System.Configuration. Il se comporte comme une liste et possède une méthode ToString remplacée qui renvoie une chaîne séparée par des virgules.

Avantages - Plus flexible qu'un tableau.

Inconvénients - Vous ne pouvez pas passer une chaîne contenant une virgule.

CommaDelimitedStringCollection list = new CommaDelimitedStringCollection();

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

string s = list.ToString(); //Huey,Dewey,Louie
10
grysik44

Vous pouvez utiliser la méthode string.Join pour faire quelque chose comme string.Join(",", o.Number, o.Id, o.whatever, ...).

edit: Comme l'a dit digEmAll, string.Join est plus rapide que StringBuilder. Ils utilisent une implémentation externe pour la chaîne.

Code de profilage (bien sûr exécuté dans la version sans symboles de débogage):

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 a pris 2 ms sur ma machine et StringBuilder.Append 5 ms. Il y a donc une différence notable. Merci à digAmAll pour l'astuce.

3
jb_

Si vous utilisez .Net 4, vous pouvez utiliser la surcharge pour string.Join qui prend un IEnumerable si vous les avez aussi dans une liste:

string.Join(", ", strings);
2
Jackson Pope

Vous pouvez remplacer la méthode ToString () de votre objet:

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