c# – GUID比较怪异

.NET有两种GUID数据类型:Guid,以“自然”方式命令GUID,以及SqlGuid,它将最后一个破折号后的六个字节视为最重要的.这种差异在这里详细解释:MSDN: Comparing GUID and uniqueidentifier Values.

但是,在这两种情况下,应该保持以下内容(假设所有… s相等):

57d0affe-... < 57d0afff-... < 57d0b000-...

如果是这种情况,为什么我会得到以下输出(请参阅注释)?

using System;
using System.Data.SqlTypes;

class Program
{
    static void Main(string[] args)
    {
        var g1 = new SqlGuid("57d0affe-9d9d-11e4-bec2-e840f2ad1632");
        var g2 = new SqlGuid("57d0afff-9d9d-11e4-bec2-e840f2ad1632");
        var g3 = new SqlGuid("57d0b000-9d9d-11e4-bec2-e840f2ad1632");

        Console.WriteLine(g1 < g2); // prints True
        Console.WriteLine(g2 < g3); // prints False <- ?
        Console.ReadLine();
    }
}

据我所知,g2< g3也应该产生True.我是否误解了某些内容,或者这是框架中的一些错误?使用普通Guid而不是SqlGuid时,输出为True,如预期的那样.

解决方法:

比较有点复杂.

首先,有一些订单定义:

  private static readonly int[] x_rgiGuidOrder = new int[16]
    {10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};

然后有这种方法

private static EComparison Compare(SqlGuid x, SqlGuid y) {
        //Swap to the correct order to be compared
        for (int i = 0; i < SizeOfGuid; i++) {
            byte    b1, b2;

            b1 = x.m_value [x_rgiGuidOrder[i]];
            b2 = y.m_value [x_rgiGuidOrder[i]];
            if (b1 != b2)
                return(b1 < b2) ? EComparison.LT : EComparison.GT;
        }
        return EComparison.EQ;
    } 

然而,这不是整个故事,究竟是什么原因是来自字符串的构造函数:

    public SqlGuid(String s) {
        m_value = (new Guid(s)).ToByteArray();
    }

它创建一个新的GUID,然后使用它的字节表示.

这给了我们以下字节值:

g2 : 255 175 208 87 157 157 228 17 190 194 232 64 242 173 22 50
g3 : 0   176 208 87 157 157 228 17 190 194 232 64 242 173 22 50

在那里我们可以看到255大于0而不是相反.

你可以找到完整的源码here
小提琴如何获得字节表示是here

上一篇:c# – 使用字符串将ExecuteScalar结果转换为GUID而不使用?


下一篇:ArrayList集合的方法