To ma znaczenie. Chcesz, aby Twoje porównanie miało taki sam wynik jak porównanie w SQL Server. SQL Server używa niepodpisanych porównań w typach binarnych:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
Jeśli zrobisz to samo z long
który jest podpisany, 0xFFFFFFFFFFFFFFFF
reprezentuje -1
. Oznacza to, że twoje porównanie będzie nieprawidłowe; nie będzie pasować do tego samego porównania wykonanego w SQL Server.
To, czego na pewno chcesz, to użyć ulong
gdzie 0xFFFFFFFFFFFFFFFF
to ulong.MaxValue
.
Endianowość jest również ważna
Dodatkowo, jak zauważył Mark, BitConverter.GetUInt64
nie konwertuje prawidłowo. Mark nie ma racji - BitConverter
jest albo big-endian, albo little-endian, w zależności od systemu, na którym działa. Możesz zobaczyć to na własne oczy
. Ponadto, nawet jeśli BitConverter zawsze był little-endian, Array.Reverse
jest mniej wydajny dzięki alokacji sterty i kopiowaniu bajt po bajcie. BitConverter
jest po prostu semantycznie lub praktycznie nieodpowiednim narzędziem do pracy.
Oto, czego chcesz:
static ulong BigEndianToUInt64(byte[] bigEndianBinary)
{
return ((ulong)bigEndianBinary[0] << 56) |
((ulong)bigEndianBinary[1] << 48) |
((ulong)bigEndianBinary[2] << 40) |
((ulong)bigEndianBinary[3] << 32) |
((ulong)bigEndianBinary[4] << 24) |
((ulong)bigEndianBinary[5] << 16) |
((ulong)bigEndianBinary[6] << 8) |
bigEndianBinary[7];
}
Najczystsze rozwiązanie
Aktualizacja :Jeśli używasz platformy .NET Core 2,1 lub nowszej (lub .NET Standard 2,1), możesz użyć BinaryPrimitives.ReadUInt64BigEndian
co jest idealnie dopasowane.
Na .NET Framework, oto rozwiązanie, którego używam:Timestamp.cs
. Zasadniczo po przesłaniu do Timestamp
, nie możesz się pomylić.