2014-09-11 40 views
7

Rozważmy następujący kod:mylić o różnych implementacji GetHashCode() w przypadku krótkiego i ushort

private static void TestHashCode<T>() 
{ 
    dynamic initialValue = 10; 
    Console.WriteLine("{0}: {1}", typeof(T).Name, ((T)initialValue).GetHashCode()); 
} 

TestHashCode<int>(); 
TestHashCode<uint>(); 
TestHashCode<long>(); 
TestHashCode<ulong>(); 
TestHashCode<short>(); 
TestHashCode<ushort>(); 

wyjściowa:

Int32: 10 
UInt32: 10 
Int64: 10 
UInt64: 10 
Int16: 655370 
UInt16: 10 

Zobacz różnicę pomiędzy short i ushort? Rzeczywiście, kod źródłowy jest różny dla tych klas:

// ushort 
public override int GetHashCode() 
{ 
    return (int) this; 
} 

// short 
public override int GetHashCode() 
{ 
    return (int) (ushort) this | (int) this << 16; 
} 

Ale w tym samym czasie, GetHashCode() implementacje dla podpisanych/niepodpisanych wersjach int i long są równe:

// int and uint 
public override int GetHashCode() 
{ 
    return (int) this; 
} 

// long and ulong 
public override int GetHashCode() 
{ 
    return (int) this^(int) (this >> 32); 
} 

Czy mógłbyś wyjaśnić, dlaczego istnieje różnica między implementacjami short i ushortGetHashCode()?

+0

Być może ktoś zapomniał wykonać tę samą implementację dla niepodpisanego skrótu? .. – dasblinkenlight

+1

Uważam, że twoje pytanie jest interesujące, ale nie ma powodu, dla którego te dwie implementacje powinny być takie same lub dlaczego powinny być inne. To tylko "implementacja, która działa". Nie ma ograniczeń stwierdzających, że kod skrótu dla podpisanego/unsigned powinien być taki sam. W szczególności. Ta implementacja jest wykonana w taki sposób, że krótki i niezerowy ushort nigdy nie może mieć tego samego skrótu. Nie można tego zrobić dla int i longs, ponieważ są one co najmniej tak duże, jak hasz. –

+1

FWIW, 'sbyte' wydaje się mieć ten sam rodzaj implementacji co' short'. –

Odpowiedz

-1

w ushort GetHashCode(), kiedy to = 10;

"return (int) (ushort) this | (int) this < < 16;"

plony 0x0000000a | 0x000a0000 => 0x000a000a = 655370

w długim i ulong "return (int) this^(int) (this >> 32);" plony 0x0000000a xor 0x00000000 ==> 0x0000000a = 10;

więc domyślam się, że jeden z "GetHashCode" ma złe wykonanie.