OrderBy / ThenBy循环 – C#中的嵌套列表

我有一个嵌套列表,

List<List> intable; 

我想在哪里排序所有列。 问题是列数取决于用户输入。

像这样排序列表工作正常(假设此示例为4列)

 var tmp = intable.OrderBy(x => x[0]); tmp = tmp.ThenBy(x => x[1]); tmp = tmp.ThenBy(x => x[2]); tmp = tmp.ThenBy(x => x[3]); intable = tmp.ToList(); 

但是,当我把它放在循环中时,像这样:

 var tmp = intable.OrderBy(x => x[0]); for (int i = 1; i  x[i]); } intable = tmp.ToList(); 

它不再正常工作,只排序第四列。

这是访问修改后的闭包的情况 。 将代码更改为此,它将起作用:

 var tmp = intable.OrderBy(x => x[0]); for (int i = 1; i <= 3; i++) { var thisI = i; tmp = tmp.ThenBy(x => x[thisI]); } intable = tmp.ToList(); 

Eric Lippert撰写了一篇由两部分组成的文章,描述了这个问题。 它无法按预期工作的原因 – 简而言之 – 因为当您调用ToList()时,LINQ仅在使用i的最后一个值时进行评估。 这跟你写的一样:

 var tmp = intable.OrderBy(x => x[0]); tmp = tmp.ThenBy(x => x[3]); tmp = tmp.ThenBy(x => x[3]); tmp = tmp.ThenBy(x => x[3]); intable = tmp.ToList(); 

创建一个比较器

 class StringListComparer : IComparer> { public int Compare(List x, List y) { int minLength = Math.Min(x.Count, y.Count); for (int i = 0; i < minLength; i++) { int comp = x[i].CompareTo(y[i]); if (comp != 0) { return comp; } } return x.Count.CompareTo(y.Count); } } 

然后像这样对列表进行排序

 intable.Sort(new StringListComparer());