File path unified in Windows/MacOS/Linux We are all tremendously happy about back slashes in Windows file systems and do not think that their sole purpose is to make life complicated for smart people who are capable of using different OS. Upvote if disagree [ :) ].

Converting paths from/to Windows backward slashes is a pretty monotonous task. Here is a library class to help with it. GitHub

OSPath path = @"/foo\bar.txt";

// Windows output
WriteLine(path);            // \foo\bar.txt
WriteLine(path.Windows);    // \foo\bar.txt
WriteLine(path.Unix);       // /foo/bar.txt

// MacOS output
WriteLine(path);            // /foo/bar.txt
WriteLine(path.Windows);    // \foo\bar.txt
WriteLine(path.Unix);       // /foo/bar.txt


It also helps converting between relative and absolute paths:

OSPath ap = "/foo/bar";
WriteLine(ap.Relative.Unix); // foo/bar
WriteLine(ap.Absolute.Unix); // /foo/bar

OSPath rp = "foo/bar";
WriteLine(rp.Relative.Unix); // foo/bar
WriteLine(rp.Absolute.Unix); // /foo/bar


And to perform path arithmetic (Windows output):

OSPath root = @"/foo\bar";
WriteLine(root + "file.txt");        // \foo\bar\file.txt
WriteLine(root + "file.txt" - root); // file.txt


Library class is:

public class OSPath
{
    public static readonly OSPath Empty = "";

    public static bool IsWindows =&gt; DirectorySeparatorChar == '\\';

    public OSPath(string path)
    {
        Path = path.Trim();
    }

    public static implicit operator OSPath(string path) =&gt; new OSPath(path);
    public static implicit operator string(OSPath path) =&gt; path.Normalized;
    public override string ToString() =&gt; Normalized;

    protected string Path { get; }

    public string Normalized =&gt; IsWindows ? Windows : Unix;
    public string Windows =&gt; Path.Replace('/', '\\');
    public string Unix =&gt; Volumeless.Path.Replace('\\', '/');

    public OSPath Relative =&gt; Volumeless.Path.TrimStart('/', '\\');
    public OSPath Absolute =&gt; IsAbsolute ? this : "/" + Relative;

    public bool IsAbsolute =&gt; IsPathRooted(Path);
    public bool HasVolume =&gt; IsAbsolute &amp;&amp; Path[1] == ':';
    public OSPath Volumeless =&gt; HasVolume
        ? (this - GetPathRoot(Path)).Absolute
        : this;

    public OSPath Parent =&gt; GetDirectoryName(Path);

    public bool Contains(OSPath path) =&gt;
        Normalized.StartsWith(path);

    public static OSPath operator +(OSPath left, OSPath right) =&gt;
        new OSPath(Combine(left, right.Relative));

    public static OSPath operator -(OSPath left, OSPath right) =&gt;
        left.Contains(right)
        ? new OSPath(left.Normalized.Substring(right.Normalized.Length)).Relative
        : left;
}
There are a couple of things that bother me:

1) I don't think you have properly implemented relative and absolute paths. At least in Windows: absolute path = working directory + relative path. Your class only does this conversion correctly, if working directory is root directory, which is almost never the case in .Net. I don't know how things are in Linux, but from Windows perspective this is a surprising behavior. It should be either well documented or fixed.

2) You assume that 1:1 two-way conversion always exists. But does it? Windows is not case sensitive, Linux is. Windows has one letter volumes, Linux does not. Those are just a few differences off the top of my head. You  can replace slashes all you want but that won't give you volume information.

3) How would you add macOS to current implementation? AFAIR, it is very much like Linux, but not exactly the same, is it? To me it looks like you would have to pretty much rewrite the entire thing. This is a good indication that overall design can be improved.