2008-09-27 11 views
6

Si tengo muchos nombres de directorio como cadenas literales o contenidas en variables, ¿cuál es la forma más fácil de combinarlas para crear una ruta completa?Crear una cadena de directorio a partir de componentes en C#

Sé de

Path.Combine
pero esto solo requiere 2 parámetros de cadena, necesito una solución que pueda tomar cualquier número de parámetros de directorio.

por ejemplo:

 
string folder1 = "foo"; 
string folder2 = "bar"; 

CreateAPath("C:", folder1, folder2, folder1, folder1, folder2, "MyFile.txt") 

¿Alguna idea? ¿C# admite argumentos ilimitados en los métodos?

Respuesta

15

¿C# admite argumentos ilimitados en los métodos?

Sí, eche un vistazo a la palabra clave params. Hará que sea fácil para escribir una función que sólo llama Path.Combine el número apropiado de veces, como este (no probado):

string CombinePaths(params string[] parts) { 
    string result = String.Empty; 
    foreach (string s in parts) { 
     result = Path.Combine(result, s); 
    } 
    return result; 
} 
+0

@OregonGhost: +1, pero cambie "" a String.Empty. – user7116

+0

Y la razón por la cual: http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx – Kev

+0

Según http://bytes.com/forum/thread453111.html, no hay exactamente la diferencia entre los dos y el compilador realmente producirá exactamente la misma IL para ambos. Pero para la legibilidad, lo cambiaré. – OregonGhost

0

Prueba con esto:

public static string CreateDirectoryName(string fileName, params string[] folders) 
{ 
    if(folders == null || folders.Length <= 0) 
    { 
     return fileName; 
    } 

    string directory = string.Empty; 
    foreach(string folder in folders) 
    { 
     directory = System.IO.Path.Combine(directory, folder); 
    } 
    directory = System.IO.Path.Combine(directory, fileName); 

    return directory; 
} 

Los parametros que hace que sea tan puede agregar una cantidad infinita de cadenas.

Lo que hace Path.Combine es asegurarse de que las cadenas ingresadas no comiencen o finalicen con barras y verifique que no haya caracteres inválidos.

+0

Por favor, permita que los métodos System.IO.Path manejen cosas como recortar o agregar barras diagonales inversas. – OregonGhost

+0

OK, lo digo de manera diferente. ¿Por qué reinventar la rueda? ¿Esa cosa codificada realmente te parece más clara? ¿Qué sucede si está ejecutando un sistema * NIX con la barra inclinada siendo el separador de ruta? ¿Qué pasa si uno de los caminos es absoluto? Path.Combine maneja eso también. – OregonGhost

+0

Oh, común, ahora realmente solo estás reinventando Path.Combine. Está allí, así que úsala: http://weblogs.asp.net/rchartier/archive/2006/01/26/436584.aspx – OregonGhost

8

LINQ al rescate de nuevo. La función de extensión Aggregate se puede usar para lograr lo que desea. Considere este ejemplo:

string[] ary = new string[] { "c:\\", "Windows", "System" }; 
string path = ary.Aggregate((aggregation, val) => Path.Combine(aggregation, val)); 
Console.WriteLine(path); //outputs c:\Windows\System 
+0

Agradable. ¡Forma de conocer las operaciones de secuencia disponibles! –

+0

Microsoft hizo un trabajo realmente bueno con LINQ. Cada vez que necesito hacer algo funky con una colección, inmediatamente miro en las bibliotecas de LINQ. –

1

Prefiero usar DirectoryInfo frente a los métodos estáticos en Directory, porque creo que es mejor diseño de OO. Aquí hay una solución con métodos de extensión DirectoryInfo +, que creo que es bastante agradable de usar:

public static DirectoryInfo Subdirectory(this DirectoryInfo self, params string[] subdirectoryName) 
    { 
     Array.ForEach(
      subdirectoryName, 
      sn => self = new DirectoryInfo(Path.Combine(self.FullName, sn)) 
      ); 
     return self; 
    } 

no amo el hecho de que estoy modificando self, pero para este corto método, creo que es más limpio que haciendo una nueva variable.

El sitio de llamada lo compensa, sin embargo:

 DirectoryInfo di = new DirectoryInfo("C:\\") 
      .Subdirectory("Windows") 
      .Subdirectory("System32"); 

     DirectoryInfo di2 = new DirectoryInfo("C:\\") 
      .Subdirectory("Windows", "System32"); 

Adición de una manera de conseguir un FileInfo se deja como ejercicio (para otro SO pregunta!).

+0

¿Podría alguien explicar por qué mi respuesta es rechazada? ¿Hay algún problema que no haya visto? –

Cuestiones relacionadas