.NET, C#

Path.Combine and relative paths

Did you know what will happen when you call System.IO.Path.Combine trying to combine a rooted and relative path ? Say you have following test case, will it pass?

        [Test]
        public void Combine_WhenOnePathIsRelative_ReturnsCombinedPath()
        {
            string relativePath = @"\test\rooted\path";
            string rootedPath = @"c:\normal\path";

            var expected = @"c:\normal\pathest\rooted\path";
            var result = Path.Combine(rootedPath, relativePath);
            Assert.AreEqual(expected, result);
        }

I expected Path.Combine to be the best way to perform such a task, well apparently it fails. Above call will return only the second path. Why? Well apparently it’s by design,

paths should be an array of the parts of the path to combine. If the one of the subsequent paths is an absolute path, then the combine operation resets starting with that absolute path, discarding all previous combined paths.

as MSDN explains. No idea why a relative path is treated as a rooted path by default? Ain’t all rooted paths (i.e. those starting with server names) start with 2 forward slashes not one ? Would it really be so hard to recognize which case is it? Cost me some bad blood today, as it’s pretty damn surprising and apparently I’m not the only one who tripped over this.
Anyway if you’d like to make the above test pass, all you have to do is to remove leading slash from relative path. This will pass:

        [Test]
        public void Combine_WhenOnePathIsUnRooted_ReturnsCombinedPath()
        {
            string relativePath = @"test\rooted\path";
            string rootedPath = @"c:\normal\path";

            var expected = @"c:\normal\pathest\rooted\path";
            var result = Path.Combine(rootedPath, relativePath);
            Assert.AreEqual(expected, result);
        }

Really MSDN? If I have to do some dodgy string concatenating, just to use your function, why even bother? Why not just string.format them?

Standard

Leave a comment