Using operator overloads for concatenating file system paths in CSharp
Edit on GitHubThe past few days, I’ve been working on some cross-platform C# code. In this code, I needed to build a path to a file, by concatenating folder names. As you may know the path separator on Windows and Linux operating systems are different: one has a backward slash (\
), the other has a forward slash (/
).
Luckily for me, the .NET framework(s) contain a utility function for this: Path.Combine
handles this for me! Here’s an example:
var rootPath = ...;
var filePath = Path.Combine(rootPath, "subfolder", "another", "file.txt");
This will generate a platform-specific path:
- On Windows: “…\subfolder\another\file.txt”
- On Linux: “…/subfolder/another/file.txt”
Great! However, I found something else in the codebase I was working on (ReSharper):
var rootPath = ...;
var filePath = rootPath / "subfolder" / "another" / "file.txt";
Whoa! This almost looks like path separators! And the great thing is that this also returns a platform-specific path.
After looking at the code a bit, I realized this was just clever use of operator overloading in C#. Some code to achieve the same result as the above:
var rootPath = new FilePath(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
var path = rootPath / ".nuget" / "packages";
public struct FilePath
{
public string Path { get; }
public FilePath(string path)
{
Path = path ?? throw new ArgumentNullException(nameof(path));
}
public static FilePath operator /(FilePath left, FilePath right)
{
return new FilePath(System.IO.Path.Combine(left.Path, right.Path));
}
public static FilePath operator /(FilePath left, string right)
{
return new FilePath(System.IO.Path.Combine(left.Path, right));
}
public override string ToString()
{
return Path;
}
}
ReSharper’s internal use of operator overloads made me realize that I’ve not been using this enough in the past. It allows nice looking syntax using +
, -
, /
, … - see full list.
This could be used on more technical things (I’d love for some operators overloads like +
on an IEnumerable<>
or a collection to create a union of two collections), but also on domain objects (a >>
operator to move a Person
to a new Address
and other types of syntax abuse).
Enjoy!
9 responses