Comment peut chemin.Combiner être utilisé avec plus de 2 arguments?

Je suis surpris qu'il n'y ait pas de surcharge qui puisse prendre un tableau de chaînes. Quoi qu'il en soit, Quel est le meilleur moyen d'éviter les appels d'imbrication à Path.Combiner?

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

Cela semble inefficace car il en résulte 4 nouvelles chaînes créées juste pour obtenir 1.

22
demandé sur Robert Harvey 2009-04-17 18:23:57

3 réponses

Le côté efficacité des choses N'est pas le problème IMO-c'est le côté convivialité des choses. Personnellement, je pense qu'il devrait y avoir une surcharge de:

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

Vous devez en avoir au moins trois pour l'empêcher d'entrer en conflit avec la version à deux paramètres existante si vous écrivez simplement Path.Combine("foo", "bar") mais cela aiderait certainement à rendre le code plus clair. Pourquoi ne pas ouvrir une demande de fonctionnalité sur Connecter?

Bien sûr, vous pouvez l'implémenter vous-même (et dans une autre classe le nombre de paramètres n'a pas tellement d'importance):

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;
}
22
répondu Jon Skeet 2009-04-17 14:33:39

Si vous avez déjà un tableau ou un IEnumerable, vous pouvez le faire en une seule ligne...

// 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 ce n'est pas le cas, Que diriez-vous d'écrire votre propre méthode d'extension en string...

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

... cela vous permettrait de les enchaîner comme ça...

string result = path1.CombinePathWith(path2)
                     .CombinePathWith(path3)
                     .CombinePathWith(path4)
                     .CombinePathWith(path5)
                     .CombinePathWith(path6);
26
répondu Martin Peck 2009-04-17 15:25:27

Il est assez simple de l'implémenter vous-même:

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);
}
1
répondu Anton Gogolev 2009-04-17 14:40:05