Pregunta

Me sorprende que no hay una sobrecarga que puede tener una matriz de cadenas. De todos modos, ¿cuál es la mejor manera de evitar las llamadas de anidación a Path.Combine?

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

Esto parece ineficaz ya que resulta en cuatro nuevas cadenas se crean sólo para conseguir uno.

¿Fue útil?

Solución

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)

Es necesario tener al 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 el código más claro. ¿Por qué no abrir una de estas solicitudes en Conectar ?

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;
}

Otros consejos

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í, a continuación, escribir 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 le permitirá a la cadena de éstos como este ...

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

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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top