如何修复这个lambda表达式
本文关键字:lambda 表达式 何修复 | 更新日期: 2023-09-27 18:07:45
根据多个用户选择的列进行排序:
public override void Sort(SortFields sortFields)
{
if (sortFields == null || sortFields.Count() == 0) return;
var res = FilteredItems.OrderBy(o => o[sortFields[0].Name], sortFields[0].Ascending ? comparer : comparerDesc);
for (int x = 1; x < sortFields.Count(); x++)
res = res.ThenBy(o => o[sortFields[x].Name], sortFields[x].Ascending ? comparer : comparerDesc);
FilteredItems = new BindingList<T>(res.ToList());
if (ListChanged != null)
ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, null));
}
当然,问题在于,当调用res.ToList()时,x已被增加到比列表中最高索引大1的位置,并抛出错误。我知道我可以在每次排序之后执行ToList(),但这违背了目的,甚至不能保证对所有linq提供程序进行正确排序。我相信有一个简单的解决办法……有人能告诉我是什么吗?:)
看起来您可能被变量x
的闭包绊倒了。
该变量在循环的每次迭代中递增。最后一次加1,此时它比"sortFields"中的项数大1,条件语句的计算结果为False
,并且for
循环结束。
正如user2864740和Eric在他的文章中指出的:
闭包关闭变量,而不是值。
因此,当调用ToList()
时,链接的ThenBy
语句保留变量x
的最终值,该值比最高索引大1。
将递增式赋值给循环中的中间变量。当您调用ToList()
时,x
的最终值将无关紧要。
for (int x = 1; x < sortFields.Count(); x++)
{
int y = x;
res = res.ThenBy(o => o[sortFields[y].Name], sortFields[y].Ascending ? comparer : comparerDesc);
}
同样来自Eric的文章,这个问题(希望)很快就会得到纠正,尽管显然只在foreach
循环中,而不是for
循环中:
在c# 5中,foreach的循环变量将在逻辑上位于循环内,因此闭包每次都会在该变量的新副本上关闭。for循环不会改变。
Try
var res = FilteredItems.OrderBy(o => o[sortFields[0].Name], sortFields[0].Ascending ? comparer : comparerDesc).ToList();