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 ushort
GetHashCode()
?
Być może ktoś zapomniał wykonać tę samą implementację dla niepodpisanego skrótu? .. – dasblinkenlight
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. –
FWIW, 'sbyte' wydaje się mieć ten sam rodzaj implementacji co' short'. –