在Visual Studio的即时窗口中:

> Path.Combine(@"C:\x", "y")
"C:\\x\\y"
> Path.Combine(@"C:\x", @"\y")
"\\y"

看来它们应该是一样的。

旧的FileSystemObject.BuildPath()不是这样工作的……


当前回答

遵循Christian Graus在他的博客“我讨厌微软的事情”中的建议。合并本质上是无用的。”下面是我的解决方案:

public static class Pathy
{
    public static string Combine(string path1, string path2)
    {
        if (path1 == null) return path2
        else if (path2 == null) return path1
        else return path1.Trim().TrimEnd(System.IO.Path.DirectorySeparatorChar)
           + System.IO.Path.DirectorySeparatorChar
           + path2.Trim().TrimStart(System.IO.Path.DirectorySeparatorChar);
    }

    public static string Combine(string path1, string path2, string path3)
    {
        return Combine(Combine(path1, path2), path3);
    }
}

一些人建议名称空间应该冲突,…为了避免与System.IO.Path的名称空间冲突,我选择了Pathy。

编辑:增加空参数检查

其他回答

删除Path.Combine的第二个参数(path2)中的起始斜杠('\')。

由于不知道实际的细节,我猜测它尝试像连接相对uri那样连接。例如:

urljoin('/some/abs/path', '../other') = '/some/abs/other'

这意味着当您使用前面的斜杠连接路径时,实际上是将一个基底连接到另一个基底,在这种情况下,第二个基底优先。

原因:

第二个URL被认为是一个绝对路径,如果最后一个路径是一个绝对路径,Combine方法只会返回最后一个路径。

解决方案:

只需从第二个路径(/SecondPath到SecondPath)中删除前导斜杠/,它就会正常工作。

遵循Christian Graus在他的博客“我讨厌微软的事情”中的建议。合并本质上是无用的。”下面是我的解决方案:

public static class Pathy
{
    public static string Combine(string path1, string path2)
    {
        if (path1 == null) return path2
        else if (path2 == null) return path1
        else return path1.Trim().TrimEnd(System.IO.Path.DirectorySeparatorChar)
           + System.IO.Path.DirectorySeparatorChar
           + path2.Trim().TrimStart(System.IO.Path.DirectorySeparatorChar);
    }

    public static string Combine(string path1, string path2, string path3)
    {
        return Combine(Combine(path1, path2), path3);
    }
}

一些人建议名称空间应该冲突,…为了避免与System.IO.Path的名称空间冲突,我选择了Pathy。

编辑:增加空参数检查

我使用聚合函数强制路径组合,如下所示:

public class MyPath    
{
    public static string ForceCombine(params string[] paths)
    {
        return paths.Aggregate((x, y) => Path.Combine(x, y.TrimStart('\\')));
    }
}