Это было не так тривиально, как я думал. Вероятно, наиболее разумным решением (кроме рекурсивного построения списка) является реализация компаратора для этого, чтобы выполнить сортировку.
class DirectorySorter : IComparer<string>
{
public int Compare(string x, string y)
{
return StringComparer.Ordinal.Compare(x.Replace(Path.DirectorySeparatorChar, '\0'),
y.Replace(Path.DirectorySeparatorChar, '\0'));
var xPaths = x.Split(Path.DirectorySeparatorChar);
var yPaths = y.Split(Path.DirectorySeparatorChar);
var minLength = Math.Min(xPaths.Length, yPaths.Length);
for (int i = 0; i < minLength; i++)
{
var ires = xPaths[i].CompareTo(yPaths[i]);
if (ires != 0) return ires;
}
var lres = xPaths.Length.CompareTo(yPaths.Length);
if (lres == 0)
{
return lres;
}
else if (lres < 0)
{
var i = y.LastIndexOf(Path.DirectorySeparatorChar);
return x.Length == i ? lres : -lres;
}
else //if (lres > 0)
{
var i = x.LastIndexOf(Path.DirectorySeparatorChar);
return y.Length == i ? lres : -lres;
}
}
}
(Видя, что ответ Стека показывает, что я был почти там с тем, что у меня было изначально. Просто мне нужно было использовать ординальный компаратор строк. Так что получается, что он работает с этим изменением.)
С другой стороны, мы могли бы использовать некоторые свойства структуры каталогов, чтобы упростить эту задачу и не реализовывать компаратор.
var query = Directory
.EnumerateDirectories(@"D:\Project\uploads", "*", SearchOption.AllDirectories)
.OrderBy(name => name.Replace(Path.DirectorySeparatorChar, '\0'), StringComparer.Ordinal);