我想使用IComparer
排序点的列表。 这里是的IComparer类:
public class CoordinatesBasedComparer : IComparer
{
public int Compare(Object q, Object r)
{
Point a = (p)q;
Point b = (p)r;
if ((a.x == b.x) && (a.y == b.y))
return 0;
if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
return -1;
return 1;
}
}
在客户端代码,我试图使用这个类进行排序点p(类型的列表List<Point>
):
CoordinatesBasedComparer c = new CoordinatesBasedComparer();
Points.Sort(c);
代码中的错误了。 显然,它期待IComparer<Point>
作为参数进行排序方法。
我需要做什么做解决这一问题?
您需要实现强类型接口( MSDN )。
public class CoordinatesBasedComparer : IComparer<Point>
{
public int Compare(Point a, Point b)
{
if ((a.x == b.x) && (a.y == b.y))
return 0;
if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
return -1;
return 1;
}
}
顺便说一句,我认为你使用太多的括号,我相信他们应该当他们的编译器贡献的前提下使用。 这是我的版本:
if (a.x == b.x && a.y == b.y)
return 0;
if (a.x < b.x || (a.x == b.x && a.y < b.y))
return -1;
就像我不喜欢用的人return (0)
请注意,如果您指定一个.net 3.5 +应用程序,您可以使用LINQ哪一个更容易,甚至与排序更快。
LINQ vesion可以是这样的:
var orderedList = Points.OrderBy(point => point.x)
.ThenBy(point => point.y)
.ToList();
public class CoordinatesBasedComparer : IComparer, IComparer<Point>
{
public int Compare(Point a, Point b)
{
if ((a.x == b.x) && (a.y == b.y))
return 0;
if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
return -1;
return 1;
}
int IComparer.Compare(Object q, Object r)
{
return Compare((Point)q, (Point)r);
}
}
如果你慢我一样,在-1和1可能很难理当使用约IComparer
。 想想它的方式是,当x
应该先去,返回-1。 当y
应该首先去,返回1。
它仍然可能会比较混乱,如果你有很多的字段作为排序依据。 您可以使用一个Enum
,让您比较逻辑比1和-1更具可读性,然后把结果。
本实施例中提出的对象与前空场的量最少。
public class NullishObjectsToTheBackOfTheLine: IComparer<ClassToCompare>
{
private enum Xy
{
X = -1,
Both = 0,
Y = 1
};
//the IComparer implementation wraps your readable code in an int cast.
public int Compare(ClassToCompare x, ClassToCompare y)
{
return (int) CompareXy(x, y);
}
private static Xy CompareXy(ClassToCompare x, ClassToCompare y)
{
if (x == null && y == null) return Xy.Both;
//put any nulls at the end of the list
if (x == null) return Xy.Y;
if (y == null) return Xy.X;
if (x.Country == y.Country && x.ProductId == y.ProductId) return Xy.Both;
//put the least amount of at the front
if (x.ProductId == null && x.Country == null) return Xy.Y;
if (y.ProductId == null && y.Country == null) return Xy.X;
//put the country values that are not nulls in front
if (x.Country != y.Country) return x.Country != null ? Xy.X : Xy.Y;
//if we got this far, one of these has a null product id and the other doesn't
return x.ProductId != null ? Xy.X : Xy.Y;
}
}
public class ClassToCompare
{
public string Country { get; set; }
public string ProductId { get; set; }
}
我正在一个InvalidOperation
错误,同时添加类型的对象MyClass
一个SortedList<MyClass>
。 当时的我,不正确,实现IComparer接口。 我需要实现IComparable接口是与方法的CompareTo(MyClass的除外),而不是ICompare.Compare(MyClass的X,MyClass的Y)。 这是一个简化的例子:
SortedList<MyClass> sortedList = new SortedList<MyClass>();
MyClass a=new MyClass(), b=new MyClass();
sortedList.Add(a);
sortedList.Add(b); // Note, sort only happens once second element is added
这个固定 :
public class MyClass : IComparable<MyClass>
{
int IComparable<MyClass>.CompareTo(MyClass other)
{
// DoCompareFunction(this, other); and return -1,0,1
}
}
此被破坏(不若加入做这个SortedList<MyClass>
):
public class MyClass : IComparer<MyClass>
{
int IComparable<MyClass>.Compare(MyClass x, MyClass y)
{
// DoCompareFunction(x, y); and return -1,0,1
}
}
这是错误:
无法比较阵列中的两个元素。
在System.Collections.Generic.ArraySortHelper`1.BinarySearch(T []数组,的Int32索引,长度的Int32,T值,比较器IComparer`1)
在System.Array.BinarySearch [T](T []数组,的Int32索引,长度的Int32,T值,比较器IComparer`1)
在System.Collections.Generic.SortedList`2.Add(TKEY的键,TValue值)