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?
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, ...);
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
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.
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);
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);
}