Seb*_*rot 1 c# sorting datagridview indexoutofboundsexception
我有一段使用自定义 IComparer 对 DataGridView 进行排序的代码:
public class CustomComparer: IComparer
{
public int Compare(object x, object y)
{
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
if (row1.ReadOnly && row2.ReadOnly)
{
return 0;
}
else if (row1.ReadOnly && !row2.ReadOnly)
{
return 1;
}
else
{
return -1;
}
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,当我执行以下行时(填充行后):
grid.Sort(new CustomComparer());
Run Code Online (Sandbox Code Playgroud)
我收到 ArgumentOutOfRangeException 并显示消息“索引超出范围。参数:索引”。
进一步调查发现以下情况:
最后一个事实促使我重写 Compare() 方法以遵循 .NET 的 CompareTo 方法:
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
return row1.ReadOnly.CompareTo(row2.ReadOnly);
Run Code Online (Sandbox Code Playgroud)
这神秘地起作用了。不再抛出异常。
因此,尽管我有一个解决方法,但我想知道是否有人知道为什么这可能是一个解决方案,以及问题首先可能是什么。我查看了 CompareTo 的实现,它也返回 -1...
朱哈尔是对的,但这就是为什么他是对的:
您的实现Compare不是对称的,这意味着如果row1.ReadOnly == false您row2.ReadOnly == false返回-1,则意味着“row1小于”。如果您用相同的值进行比较,则变为小于。这可能会混淆需要对称的排序算法。 row2row2 row1Compare
正确的比较应该是:
if (row1.ReadOnly == row2.ReadOnly) // change && to ==
{
return 0;
}
else if (row1.ReadOnly && !row2.ReadOnly)
{
return 1;
}
else
{
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这很可能bool.CompareTo(bool)会返回,这就是为什么你的“解决方法”(在我看来,这是一个更好的解决方案)有效。