Test(subPath: "c:/foo/bar", basePath: "c:/foo");
Test(subPath: "c:/foo/bar/qux", basePath: "c:/foo");
Test(subPath: "c:/foo", basePath: "c:/foo/bar");
Test(subPath: "c:/FOO/bar", basePath: "C:/foo");
Test(subPath: "c:/foo/bar", basePath: "c:/foo/");
Test(subPath: "c:/foo/bar/", basePath: "c:/foo");
Test(subPath: "c:/foo/bar", basePath: "c:/foo/bar");
Test(subPath: "d:/foo/bar", basePath: "c:/foo");
Test(subPath: "c:/foo/../foo/bar", basePath: "c:/foo");
Test(subPath: "c:/foo/.bar", basePath: "c:/foo");
void Test(string subPath, string basePath) {
var isSubPath = subPath.IsSubPathOf(basePath);
var infix = isSubPath ? " " : " NOT ";
Console.WriteLine($"'{subPath}'\tis{infix}a sub path of\t'{basePath}'\t({Path.GetRelativePath(basePath, subPath)})");
public static class Ext {
public static bool IsSubPathOf(this string subPath, string basePath) {
var rel = Path.GetRelativePath(basePath, subPath);
return !rel.StartsWith('.') && !Path.IsPathRooted(rel);