2011-02-03 31 views
32

Tengo un objeto que contiene muchos valores, algunos de ellos (no todos los valores del objeto) deben colocarse en una cadena csv. Mi enfoque fue este:Crear cadenas separadas por comas C#?

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

De alguna manera creo que hay una manera mejor y más elegante?

+0

En general, se considera menos eficiente para concatenar cadenas con el símbolo '+'. Crea más objetos para ser basura recolectada. –

+0

[Separación de coma manual en comparación con la genial clase CommaDelimitedStringCollection!] (Http://izlooite.blogspot.com/2009/12/manual-comma-separation-versus-cool.html) –

Respuesta

73

Si coloca todos sus valores en una matriz, al menos puede usar string.Join.

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

También puede utilizar la sobrecarga de string.Join que toma params string como el segundo parámetro como esto:

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

+1 para usar una matriz entre las que se mantiene el código es más legible cuando hay más de "unos pocos" valores. – Bazzz

+0

@Bazzz - Sí, puede ser complicado si ingresas más de 10 parámetros en la llamada al método de unión. Creo que el primer enfoque es el más limpio, pero por unos pocos valores, el segundo también está bien. –

+0

¿Por qué dos votos a favor en esta respuesta? Se agradecerá una razón para que todos sepan cuál es el problema con esta respuesta. –

1

Se podría reemplazar el método de su objeto ToString():

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

Esto solo es útil si sabe exactamente la cantidad de elementos que quiere poner en la cadena. string.Join es probablemente un mejor ajuste. –

+0

Sí, pero como quiere crear un archivo csv, los elementos probablemente serán los mismos siempre. No lo sé, es una cuestión de preferencia. –

+0

Supuse a partir de la pregunta que siempre quiere los mismos campos, por lo que definitivamente sabe la cantidad de elementos. No hay nada de malo con esta respuesta, aunque realmente no me gusta anular ToString aquí, ya que puede no ser lo suficientemente general. +1 de mí de todos modos. – fearofawhackplanet

3

Usted puede usar el método string.Join para hacer algo como string.Join(",", o.Number, o.Id, o.whatever, ...).

editar: Como digEmAll dijo, string.Join es más rápido que StringBuilder. Usan una implementación externa para la cadena. Únete.

perfiles de código (del recorrido de la carrera en la liberación sin símbolos de depuración):

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 tomó 2 ms en mi máquina y StringBuilder.Append 5ms. Entonces hay una diferencia notable. Gracias a digAmAll por la pista.

+2

'string.Join' es tan rápido como' StringBuilder' (si no es un poco más rápido) porque ambos asignan una sola cadena – digEmAll

+0

El problema con la cadena normal concat (por ejemplo, usando string1 + = string2) es que el string1 original se descarta (ya que las cadenas son inmutables), y la nueva suma de string1 y string2 es apuntada por string1, y eso no es muy eficiente si se hace de forma repetida. Sin embargo, como digEmAll también señala, string.Join por supuesto, solo asigna la cadena una vez. No una vez por cada elemento en la matriz. –

+0

Una desventaja de 'string.Join' (hasta .NET 4.0) es que requiere una matriz de cadenas, lo que te obliga a asignar una si solo tienes un' IEnumerable 'genérico ... de todos modos .NET 4.0 ha corregido este problema – digEmAll

1

Si está utilizando .Net 4 se puede utilizar la sobrecarga para string.Join que tiene un IEnumerable si los tiene en una lista, también:

string.Join(", ", strings); 
6

Otro enfoque consiste en utilizar la clase CommaDelimitedStringCollection del Sistema .Configuration namespace/assembly. Se comporta como una lista y además tiene un método ToString modificado que devuelve una cadena separada por comas.

Pros - Más flexible que una matriz.

Contras: no se puede pasar una cadena que contenga una coma.

CommaDelimitedStringCollection list = new CommaDelimitedStringCollection(); 

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

string s = list.ToString(); //Huey,Dewey,Louie 
Cuestiones relacionadas