2010-10-19 10 views
10

Como dice el título: ¿Por qué string.Join necesita tomar una matriz en lugar de un Enumerable? Esto me sigue molestando, ya que tengo que agregar un .ToArray() cuando necesito crear una cadena unida a partir del resultado de una expresión LINQ.¿Cuál es la razón de string.Join necesita tomar una matriz en lugar de una IEnumerable?

Mi experiencia me dice que aquí me falta algo obvio.

+2

Te complacerá saber que acepta 'IEnumerable ' en.NET 4 –

+0

Supongo que se agregó antes de que existiera IEnumerable. – asawyer

+0

string.Join estuvo aquí mucho antes que Linq. ¿Cómo te molesta? Solo quedan unos pocos caracteres más para escribir. –

Respuesta

9

de actualización a .NET 4.0 y usa overload que acepta IEnumerable<string>. De lo contrario, simplemente acepte que fue un problema pendiente durante mucho tiempo que no fue abordado hasta .NET 4.0. ¡Puede solucionar el problema creando también su propio método de extensión!

public static class StringEnumerableExtensions { 
    public static string Join(this IEnumerable<string> strings, string separator) { 
     return String.Join(separator, strings.ToArray()); 
    } 
} 

Uso:

IEnumerable<string> strings; 
Console.WriteLine(strings.Join(", ")); 
+0

Jason, muchas gracias, ¡la programación se volvió tan alegre! ':)' – sbi

+0

BTW, en realidad escribí un 'Join (este IEnumerable cadenas, separador de cadenas)' además de eso. Me enamoré tanto, pasé por 100kLoC y adapté todos los usos de 'string.Join()'. – sbi

3

Ya no es así. .NET 4 agregó some overloads para que sea más fácil de usar. En particular, no solo no necesita pasar una matriz, tampoco necesita ser una secuencia de cadenas. String.Join(String, IEnumerable<T>) llamará al ToString en cada elemento de la secuencia.

Si no está usando .NET 4 pero está realizando muchas operaciones de unión de cadenas, siempre puede escribir sus propios métodos, por supuesto.

+0

¿Me estás diciendo que no hay razón para que .NET <4 lo haga? – sbi

+0

@sbi: Sí. Es algo que MS probablemente no se había dado cuenta sería tan útil para los desarrolladores. No necesita ninguna característica nueva de .NET 4, que yo sepa. –

+0

Y aquí estaba esperando un tratamiento prolongado y educativo sobre las razones por las que debe ser una matriz ... – sbi

8

Overloads of Join that take an IEnumerable<T> argument se introdujeron en .NET 4 - si no está utilizando .NET 4 entonces me temo que tiene que pasar una serie o escribir su propia implementación.

Supongo que la razón es simplemente que no se consideró lo suficientemente importante cuando se diseñó el marco por primera vez. IEnumerable<T> se hizo mucho más prominente con la introducción de LINQ.

(Por supuesto, no había ningún tipo genérico en .NET cuando se estaba diseñando, pero no hay ninguna razón por la que no podrían haberlo hecho con IEnumerable no genérico simple si hubieran pensado que valía la pena).

y no hay razón para que no pueda rodar su propia versión de Join que toma un IEnumerable<T> si siente que lo necesita y no es capaz de actualizar a .NET 4.

+0

... a menos que se escriba * array-to-'IEnumerable '*, supongo? Eso es lo que la gente de Java estamos acostumbrados a hacer, de todos modos. – Esko

0

Conjeturaría que string.join requiere la capacidad de iterar a través de la matriz dos veces (una vez para medir la longitud, y una vez para hacer la copia). Algunas clases que implementan iEnumerable se pueden unir con éxito en una matriz de cadenas haciendo una pasada para contar la longitud, llamando a Restablecer en el enumerador y utilizando una segunda pasada para copiar los datos, pero como iEnumerable no admite ni una propiedad de Capacidades ni una familia de clases derivadas como iMultiPassEnumerable, las únicas formas en que String.Join podría aceptar con seguridad un iEnumerable sería (1) enumerar a algún tipo de lista y ejecutar la combinación en eso, (2) adivinar el tamaño de cadena de destino y reasignar como necesario, o (3) combinar los enfoques, agrupando cadenas cortas en grupos de hasta, por ejemplo, 8K, y luego combinar todos los clústeres en un resultado final (que sería una mezcla de clústeres preconcabados y cadenas largas de la matriz original).

Si bien me gustaría decir que sería útil para String.Join incluir una sobrecarga que convierta un iEnumerable en una lista, no veo que brinde más eficiencia que la conversión manual (a diferencia del versión de matriz de String.Join, que es más eficiente que unir cadenas manualmente de forma individual).

Cuestiones relacionadas