Path.Combine如何与两个以上的参数一起使用?

时间:2009-04-17 14:23:58

标签: .net string path io concatenation

我很惊讶没有可以采用字符串数组的重载。无论如何,避免将调用嵌套到Path.Combine的最佳方法是什么?

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

这似乎效率低下,因为它会导致创建四个新字符串以获得一个。

3 个答案:

答案 0 :(得分:27)

如果您已经有一个数组或IEnumerable< T>然后你可以在一行中做到这一点......

// 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);

如果没有,那么将自己的扩展方法写入字符串...

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

...这会让你像这样链接......

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

答案 1 :(得分:22)

事情的效率方面不是问题IMO - 它是事物的可用性方面。我个人认为应该有一个超载:

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

如果你只是写Path.Combine("foo", "bar"),你需要至少有三个以防止它与现有的双参数版本发生冲突,但它肯定有助于使代码更清晰。为什么不在Connect上打开功能请求?

当然,你可以自己实现这个(在另一个类中,参数的数量并不重要):

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

答案 2 :(得分:1)

自己实施它非常简单:

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