The CLR is full of surprises.
Microsoft has a built-in System.IO.Path class, to deal with all the path parsing issues we often run across. One of the most useful methods in there can get rid of all the special case code we write to combine path strings. How many times have you written something like this to combine two path strings -- taking into account whether you need to add a slash between the path strings or not:
String path1 = @"C:\ABC"; // may or may not end in a slash
String path2 = @"DEF"; // may or may not start with a slash
String path = path1.TrimEnd('\\') + "\\" + path2.TrimStart('\\')
That one line of code works, but it creates 3 strings, calls two methods, and in general looks ugly.
Enter the Path class.
Path.Combine( path1, path2 )
This is a sweet routine - you use it to combine two strings and it takes care of figuring out whether you need a slash between the parts of the path or not. But there's a hitch.
See if you can predict the output of these lines:
Console.WriteLine( Path.Combine( @"C:\ABC", @"DEF" ));
Console.WriteLine( Path.Combine( @"C:\ABC\", @"DEF" ));
Console.WriteLine( Path.Combine( @"C:\ABC", @"\DEF" ));
Console.WriteLine( Path.Combine( @"C:\ABC\", @"\DEF" ));
When you think you know the answer, read on...
The first two work as expected. It correctly builds the path.
Path.Combine( @"C:\ABC", @"DEF" ) -> C:\ABC\DEF
Path.Combine( @"C:\ABC\", @"DEF" ) -> C:\ABC\DEF
But here's the surprise. If your second piece of the path starts with a backslash, it assumes you must want it to be the root. So it ignores the first parameter!
Path.Combine( @"C:\ABC", @"\DEF" ) -> \DEF
Path.Combine( @"C:\ABC\", @"\DEF" ) -> \DEF
The documentation for Path.Combine makes this clear in its remarks. But really now, is this a useful feature? Path.Combine would have been much more useful if it simply took two paths and concatenated them properly. For my money, having these four examples return C:\ABC\DEF would have been a better choice.
What Path.Combine IS useful for would be better documented like this:
Path.Combine( defaultDirectory, userPath );
If I had seen that as the description of the parameters, this annoying behavior would not have surprised me. More importantly: I wouldn't have dreamed of using it for "combining" paths.
Ok, I'll stop dreaming.