public class foo {
int ID { get; set; }
byte[] sort { get; set; }
}
public class barMaster {
public void FooSource() {
return List<foo> FromDataSource;
}
public void display() {
List<foo> sortedFoo = FooSource().OrderBy(f => f.sort);
UIElement = sortedFoo;
}
我有一组包含byte []属性的对象,我希望OrderBy,但是,OrderBy(byte [])会抛出错误:
System.ArgumentException: At least one object must implement IComparable.
我可以对OrderBy byte []值做什么?
答案 0 :(得分:5)
您无法直接通过byte[]
订购,因为数组未实现IComparable
。您需要按第一个字节排序(即:OrderBy(f => f.sort[0])
或其他适当的顺序),或编写您自己的IComparer<byte[]>
并在OrderBy的适当重载中使用它。
答案 1 :(得分:4)
作为you've indicated that the arrays are of variable length(因为它是SQL Server层次结构ID),您绝对需要创建自定义IComparer<byte[]>
实现。
逻辑很简单:
n
字节,其中n
是两个数组中较小的字节数。当在任何字节之间检测到差异时,返回不同字节的比较结果。n
字节相等,则返回两个数组长度的比较。这样,给出一组这样的数据:
00 01 02
00 01
01
排序后,您将获得的结果是:
00 01
00 01 02
01
那就是说,这就是你的IComparer<byte[]>
实现的样子:
// I could be wrong in that this is called natural order.
class NaturalOrderByteArrayComparer : IComparer<byte[]>
{
public int Compare(byte[] x, byte[] y)
{
// Shortcuts: If both are null, they are the same.
if (x == null && y == null) return 0;
// If one is null and the other isn't, then the
// one that is null is "lesser".
if (x == null && y != null) return -1;
if (x != null && y == null) return 1;
// Both arrays are non-null. Find the shorter
// of the two lengths.
int bytesToCompare = Math.Min(x.Length, y.Length);
// Compare the bytes.
for (int index = 0; index < bytesToCompare; ++index)
{
// The x and y bytes.
byte xByte = x[index];
byte yByte = y[index];
// Compare result.
int compareResult = Comparer<byte>.Default.Compare(xByte, yByte);
// If not the same, then return the result of the
// comparison of the bytes, as they were the same
// up until now.
if (compareResult != 0) return compareResult;
// They are the same, continue.
}
// The first n bytes are the same. Compare lengths.
// If the lengths are the same, the arrays
// are the same.
if (x.Length == y.Length) return 0;
// Compare lengths.
return x.Length < y.Length ? -1 : 1;
}
}
顺便说一句,如果您的字节数组保证长度相同,作为替代方案,您可以动态创建order by子句,按第一个元素排序,然后按第二个元素排序等,如下所示:
static IEnumerable<foo> OrderBySortField(this IEnumerable<foo> items,
int sortLength)
{
// Validate parameters.
if (items == null) throw new ArgumentNullException("items");
if (sortLength < 0) throw
new ArgumentOutOfRangeException("sortLength", sortLength,
"The sortLength parameter must be a non-negative value.");
// Shortcut, if sortLength is zero, return the sequence, as-is.
if (sortLength == 0) return items;
// The ordered enumerable.
IOrderedEnumerable<foo> ordered = items.OrderBy(i => i.sort[0]);
// Cycle from the second index on.
for (int index = 1; index < sortLength; index++)
{
// Copy the index.
int indexCopy = index;
// Sort by the next item in the array.
ordered = ordered.ThenBy(i => i.sort[indexCopy]);
}
// Return the ordered enumerable.
return ordered;
}
然后你可以简单地这样称呼它:
// You have to supply the length of the array you're sorting on.
List<foo> sortedFoo = FooSource().
OrderBySortField(sortLength).ToList();
答案 2 :(得分:0)
不幸的是,就我所知,你不能按字节数组排序。
你能做的就是让你的foo类实现IComparable。然后在覆盖compareTo方法中,在调用中根据需要编写字节数组的比较。然后,您可以通过简单的排序来重新排序订单:
FooSource().Sort();
答案 3 :(得分:0)
我知道,这是一个古老的问题,但是在特定情况下,当字节数组包含数字(例如IP地址)时,可以使用BitConverter类:
OrderBy(d => BitConverter.ToInt32(d.bytearray,0))