You can build a comparator ( https://msdn.microsoft.com/pt-br/library/8ehhxeaf%28v=vs.110%29.aspx ) that compare strings containing numbers, and pass it to method OrderBy:lista.OrderBy(c => c.Str, meuComparador)
This comparison you can do using https://msdn.microsoft.com/pt-br/library/8yttk7sy%28v=vs.110%29.aspx to split the string into the positions in which numbers are found:Regex.Split(str, @"(\d+)")
A regex \d+ serves to indicate that we want find strings with 1 or + digits:\d means a digit any+ means find one or more of the previous itemThe parenthesis around \d+, serves to indicate to the split, that the number should be kept in the array of the split string, so that we can use it in the comparison. Here's how different it is:Regex.Split("a123b", @"\d+") => array ["a", "b"]
Regex.Split("a123b", @"(\d+)") => array ["a", "123", "b"]
The comparator class of strings containing numbersI've implemented the class to be present to anyone in the future. == sync, corrected by elderman ==public class ComparerStringComNumeros : IComparer<string>
{
public static ComparerStringComNumeros Instancia
= new ComparerStringComNumeros();
private ComparerStringComNumeros() { }
public int Compare(string x, string y)
{
var itemsA = Regex.Split(x, @"(\d+)");
var itemsB = Regex.Split(y, @"(\d+)");
for (int it = 0; ; it++)
{
if (it == itemsA.Length)
return it == itemsB.Length ? 0 : -1;
if (it == itemsB.Length)
return 1;
if ((it % 2) == 0)
{
// parte não numérica
var strCompare = StringComparer.CurrentCulture.Compare(
itemsA[it],
itemsB[it]);
if (strCompare != 0)
return strCompare;
}
else
{
// parte numérica
var numCompare = Comparer<int>.Default.Compare(
int.Parse(itemsA[it]),
int.Parse(itemsB[it]));
if (numCompare != 0)
return numCompare;
}
}
}
}
Test of the above class, using the OrderBy:public void TesteDeOrdenacao()
{
var l = new[]
{
"x0.2",
"m1.2",
"m1.04",
"m10.0",
"x1.2",
"x1.04",
"m10.0.0",
"x1.2.2",
"x1.04.8 a",
"x1.04.8 b",
"x1.04.8 c2",
"x1.04.8 c3",
"x1.04.8 c1",
"x10.0",
"m0.2"
};
var l2 = l.OrderBy(x => x, ComparerStringComNumeros.Instancia).ToList();
// l2 irá conter:
//
// "m0.2",
// "m1.2",
// "m1.04",
// "m10.0",
// "m10.0.0",
// "x0.2",
// "x1.2",
// "x1.2.2",
// "x1.04",
// "x1.04.8 a",
// "x1.04.8 b",
// "x1.04.8 c1",
// "x1.04.8 c2",
// "x1.04.8 c3",
// "x10.0"
}
How to use in your code:var dirs = parentdir.GetDirectories()
.OrderBy(c => c.Name, ComparerStringComNumeros.Instancia)
.ToList();