How can Path.Combine be used with more than two arguments?

前端 未结 3 1712
孤城傲影
孤城傲影 2021-02-18 14:02

I\'m surprised there\'s not an overload that can take a string array. Anyway, what is the best way to avoid nesting calls to Path.Combine?

pathValue = Path.Combi         


        
相关标签:
3条回答
  • 2021-02-18 14:07

    The efficiency side of things isn't the problem IMO - it's the usability side of things. Personally I think there ought to be an overload of:

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

    You need to have at least three to prevent it from clashing with the existing two-parameter version if you just write Path.Combine("foo", "bar") but it would certainly help to make code clearer. Why not open a feature request on Connect?

    Of course, you can implement this yourself (and in another class the number of parameters doesn't matter so much):

    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;
    }
    
    0 讨论(0)
  • 2021-02-18 14:14

    It's pretty straightforward to implement it yourself:

    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);
    }
    
    0 讨论(0)
  • 2021-02-18 14:17

    If you already have an array or an IEnumerable<T> then you could do this in one line...

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

    If not, then write your own extension method to string...

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

    ... that would allow you to chain these like this...

    string result = path1.CombinePathWith(path2)
                         .CombinePathWith(path3)
                         .CombinePathWith(path4)
                         .CombinePathWith(path5)
                         .CombinePathWith(path6);
    
    0 讨论(0)
提交回复
热议问题