一个自定义排序器,为何无限循环执行
一个自定义排序器,为什么无限循环执行?
在上面的代码中,有一个List<DataRow>类型的对象,有一个自定义的排序器,使用这个排序器对ListRows排序。
结果是,无法输出ListRows.Count(),通过设置断点,发现代码在无限循环执行PersonComparer 方法,请问,这是什么故障?
如果取消ToList()方法,写成:var c = Enumerable.OrderBy(ListRows, MyFunc, new PersonComparer());这种,就不会无限循环执行PersonComparer 方法,
这是何故呢?
------解决思路----------------------
ToList()之后才会无线循环???
ToList了可以直接list.Count了啊,干嘛还要扩展方法
------解决思路----------------------
因为你PersonComparer实现有错误,它一会儿说A>B,一会儿说B>A,一会儿说A>A。结果就是排序的算法被迷惑了,不断的调整位置,没完没了。
如果‘取消ToList()方法’,那么var c = ...本身只是给出一个表达式(还没有真正开始排序),因此还看不到死循环。
而一旦展开了表达式(比如ToList),排序就会真正运行。
要解决问题很简单,正确实现‘比较’就可以了:
------解决思路----------------------
LZ说他ToList没死循环,是list.Count()出现死循环……
如果没ToList,直接调用Count()楼主又说不会死循环,等其它人来解惑
当然目前来说自己还没做个测试验证,也许该实际做过验证……
------解决思路----------------------
public int Compare(DataRow x, DataRow y)
{
return 1;
}
这里返回1,表示x比y大。
想象这种比较:
------解决思路----------------------
public int Compare(DataRow x, DataRow y)
{
return 1;
}
你这个都没得比较当然无限了。你总得有个比较才行
{
static void Main(string[] args)
{
DataTable tbl = new DataTable("Customers");
tbl.Columns.Add("PersonName", typeof(string));
tbl.Columns.Add("PersonAge", typeof(Int32));
DataRow row = tbl.NewRow();
row["PersonName"] = "张三";
row["PersonAge"] = "22";
tbl.Rows.Add(row);
row = tbl.NewRow();
row["PersonName"] = "李四";
row["PersonAge"] = "25";
tbl.Rows.Add(row);
List<DataRow> ListRows = new List<DataRow>();
foreach (DataRow r in tbl.Rows)
{
ListRows.Add(r);
}
Func<DataRow, DataRow> MyFunc = new Func<DataRow, DataRow>((Row) =>
{
return Row;
});
ListRows = Enumerable.OrderBy(ListRows, MyFunc, new PersonComparer()).ToList();
Console.WriteLine(ListRows.Count());
Console.ReadKey();
}
}
public class PersonComparer : IComparer<DataRow>
{
public int Compare(DataRow x, DataRow y)
{
return 1;
}
}
在上面的代码中,有一个List<DataRow>类型的对象,有一个自定义的排序器,使用这个排序器对ListRows排序。
结果是,无法输出ListRows.Count(),通过设置断点,发现代码在无限循环执行PersonComparer 方法,请问,这是什么故障?
如果取消ToList()方法,写成:var c = Enumerable.OrderBy(ListRows, MyFunc, new PersonComparer());这种,就不会无限循环执行PersonComparer 方法,
这是何故呢?
------解决思路----------------------
ToList()之后才会无线循环???
ToList了可以直接list.Count了啊,干嘛还要扩展方法
------解决思路----------------------
因为你PersonComparer实现有错误,它一会儿说A>B,一会儿说B>A,一会儿说A>A。结果就是排序的算法被迷惑了,不断的调整位置,没完没了。
如果‘取消ToList()方法’,那么var c = ...本身只是给出一个表达式(还没有真正开始排序),因此还看不到死循环。
而一旦展开了表达式(比如ToList),排序就会真正运行。
要解决问题很简单,正确实现‘比较’就可以了:
public class PersonComparer : IComparer<DataRow>
{
public int Compare(DataRow x, DataRow y)
{
return (int)x["PersonAge"] - (int)y["PersonAge"];
}
}
------解决思路----------------------
LZ说他ToList没死循环,是list.Count()出现死循环……
如果没ToList,直接调用Count()楼主又说不会死循环,等其它人来解惑
当然目前来说自己还没做个测试验证,也许该实际做过验证……
------解决思路----------------------
我直接return 1,有什么错啊,你说的"一会儿说A>B,一会儿说B>A,一会儿说A>A "从何说起啊?
public int Compare(DataRow x, DataRow y)
{
return 1;
}
这里返回1,表示x比y大。
想象这种比较:
PersonComparer comparer = new PersonComparer();
DataRow A = ListRows[0];
DataRow B = ListRows[1];
int d1 = comparer.Compare(A, B); // 返回1,A>B
int d2 = comparer.Compare(B, A); // 返回1,B>A
int d3 = comparer.Compare(A, A); // 返回1,A>A
------解决思路----------------------
public int Compare(DataRow x, DataRow y)
{
return 1;
}
你这个都没得比较当然无限了。你总得有个比较才行