Я пытался использовать код, заимствованный из здесь, чтобы отсортировать коллекцию пользовательских объектов с моим приложением. Обычно сортировка работает нормально, пока я не столкнусь со следующими строками
D-016.0,
D-016.,
D-016.00,
D-016.000 001,
D-016.000 002,
D-016.000,
D-016.00 003,
D-016.00 002,
D-016. 001,
D-016. 002,
D-016.0 001,
D-016.00 001
который по какой-то очень странной причине возвращает коллекцию в порядке
D-016.00,
D-016.000,
D-016.0,
D-016.000 001,
D-016. 001,
D-016.0 001,
D-016.00 001,
D-016.00 002,
D-016.000 002,
D-016. 002,
D-016.00 003,
D-016.
Коллекция, которую я ожидаю увидеть, будет выглядеть так, как показал бы проводник Windows, что должно быть
D-016. 001,
D-016. 002,
D-016.,
D-016.000 001,
D-016.000 002,
D-016.000,
D-016.00 001,
D-016.00 002,
D-016.00 003,
D-016.00,
D-016.0 001,
D-016.0,
Следуя предложению Natural Sort Order in C#, опубликованному Майкл Книскерн, я попытался реализовать ответ, который использует shlwapi.dll, и это возвращает порядок, который я ожидал бы увидеть в соответствии с последней коллекцией, перечисленной выше. Однако этот подход работает только в Windows 7 и возвращает неравномерную коллекцию в Windows XP.
Я подозреваю, что файлы, указанные как D-016.00, D-016.0 и D-016.000, получат список нулей, объединенных при синтаксическом анализе в int, что приведет к этой ошибке. Однако я не могу точно понять, как именно это исправить (слишком новичок в этих интерфейсах сравнения). Может ли кто-нибудь предложить решение для этого?
Ниже приведен код, который я сейчас использую
public class NaturalSorter<T> : IComparer<string>, IDisposable
{
private readonly bool ascending;
private Dictionary<string, string[]> table = new Dictionary<string, string[]>();
public NaturalSorter(bool inAscendingOrder = true)
{
ascending = inAscendingOrder;
}
#region IComparer Members
public int Compare(string[] x, string[] y)
{
throw new NotImplementedException();
}
#endregion
#region IComparer Members
int IComparer<string>.Compare(string x, string y)
{
if (x == y)
return 0;
string[] x1, y1;
if (!table.TryGetValue(x, out x1))
{
x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)");
table.Add(x, x1);
}
if (!table.TryGetValue(y, out y1))
{
y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)");
table.Add(y, y1);
}
int returnVal = 0;
for (int i = 0; i < x1.Length && i < y1.Length; i++)
{
if (x1[i] != y1[i])
{
returnVal = PartCompare(x1[i], y1[i]);
return ascending ? returnVal : -returnVal;
}
}
if (y1.Length > x1.Length)
{
returnVal = 1;
}
else if (x1.Length > y1.Length)
{
returnVal = -1;
}
else
{
returnVal = 0;
}
return ascending ? returnVal : -returnVal;
}
private static int PartCompare(string left, string right)
{
int x, y;
if (!int.TryParse(left, out x))
return left.CompareTo(right);
if (!int.TryParse(right, out y))
return left.CompareTo(right);
return x.CompareTo(y);
}
#endregion
public void Dispose()
{
table.Clear();
table = null;
}
}
D-016., D-016. 001, D-016. 002, D-016.0, ...
- person JosephHirn   schedule 29.01.2013