2009-04-17 28 views
20

Me sorprende que no haya una sobrecarga que pueda tomar una matriz de cadenas. De todos modos, ¿cuál es la mejor manera de evitar anidar llamadas a Path.Combine?¿Cómo se puede usar Path.Combine con más de 2 argumentos?

pathValue = Path.Combine(path1, Path.Combine(path2, Path.Combine(path3, path4))) 

Esto parece ineficaz ya que resulta en 4 nuevas cadenas se crean sólo para obtener 1.

+5

En .Net4 Path. Combine() se cambió para tomar más de dos cadenas como esta: Path.Combine (path1, path2, path3, ...). ¡Dulce! – fredw

+1

Bueno, mierda. Microsoft no tenía el sentido común para implementarlo en NET 2.0 o incluso 3.5? – david

Respuesta

21

El lado de la eficiencia de las cosas no es el problema de la OMI - es el lado usabilidad de las cosas. Personalmente creo que debería haber una sobrecarga de:

Combine(string first, string second, string third, params string[] others) 

Usted necesita tener por lo menos tres para evitar que choque con la versión de dos parámetros existente si usted acaba de escribir Path.Combine("foo", "bar") pero sin duda ayudará a hacer que el código más claro. ¿Por qué no abrir una solicitud de función en Connect?

Por supuesto, se puede implementar esto por sí mismo (y en otra clase el número de parámetros no importa mucho):

public static string CombinePaths(string first, params string[] others) 
{ 
    // Put error checking in here :) 
    string path = first; 
    foreach (string section in others) 
    { 
     path = Path.Combine(path, section); 
    } 
    return path; 
} 
+5

Downvoters: por favor, den una razón, de lo contrario su voto no tiene sentido. –

+6

el deseo del OP ha sido otorgado. Soporte para Path.Combine (params) ha sido agregado en .net 4 Beta2 - http://blogs.msdn.com/bclteam/archive/2009/10/21/what-s-new-in-the-bcl-in -net-4-beta-2-justin-van-patten.aspx – Gishu

+1

Resharper sugiere un evento más conciso para los demás.Agregado (primero, Path.Combine) – username

1

Es bastante sencillo de implementar por sí mismo:

public string Combine(params string[] paths) 
{ 
    char[] pathSeparators = new char[] 
     { Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar, Path.VolumeSeparatorChar }; 

    if(paths == null) throw new ArgumentNullException("paths"); 
    if(paths.Length == 1) return paths[0]; 

    StringBuilder pathBuilder = new StringBuilder(); 

    foreach(string path in paths) 
    { 
     if(Path.IsPathRooted(path)) 
      pathBuilder = new StringBuilder(path); 
     else 
     { 
      char last = pathBuilder.Length > 0 ? 
       pathBuilder[pathBuilder.Length - 1] : 
       path[path.Length - 1]; 

      if(Array.IndexOf(pathSeparators, last) == -1) 
       pathBuilder.Append(Path.DirectorySeparatorChar); 

      pathBuilder.Append(path); 
     } // else 
    } // foreach 

    return pathBuilder.ToString(); 
} 

[Test()] 
public void CombinePaths() 
{ 
    string result = Combine(@"C:\Program Files\", @"Microsoft.NET", @"ADOMD.NET\", "90", "msadomdx.dll"); 
    Assert.AreEqual(@"C:\Program Files\Microsoft.NET\ADOMD.NET\90\msadomdx.dll", result); 
} 
25

Si ya tiene una matriz o un IEnumerable entonces se podría hacer esto en una línea ...

// I'm assuming that you've got an array or IEnumerable<T> from somewhere 
var paths = new string[] { path1, path2, path3, path4, path5, path6 }; 

string result = paths.Aggregate(Path.Combine); 

Si no es así, ¿qué hay de la escritura de su propio método de extensión de cadena ...

public static class PathExtension 
{ 
    public static string CombinePathWith(this string path1, string path2) 
    { 
     return Path.Combine(path1, path2); 
    } 
} 

... que permitiría a la cadena de éstos así ...

string result = path1.CombinePathWith(path2) 
        .CombinePathWith(path3) 
        .CombinePathWith(path4) 
        .CombinePathWith(path5) 
        .CombinePathWith(path6); 
+3

Genial, no sabía acerca de Enumerable.Aggregate! –

+0

@Christian. Aggregate es una herramienta muy poderosa para tener a mano. –

Cuestiones relacionadas