Je suis juste curieux parce que je suppose que cela aura un impact sur la performance. Est-ce qu’il considère la chaîne complète? Si oui, il sera lent sur une longue chaîne. Si elle ne considère qu’une partie de la chaîne, elle aura de mauvaises performances (par exemple, si elle ne considère que le début de la chaîne, elle aura de mauvaises performances si un HashSet contient principalement des chaînes avec la même chose).
Veillez à obtenir le code source de la source de référence lorsque vous avez des questions de ce type. Il y a beaucoup plus que ce que vous pouvez voir dans un décompilateur. Choisissez celui qui correspond à votre cible .NET préférée, la méthode a beaucoup changé entre les versions. Je vais juste en reproduire la version .NET 4.5 ici, extraite de Source.NET 4.5 \ 4.6.0.0 \ net \ clr \ src \ BCL \ System \ Ssortingng.cs \ 604718 \ Ssortingng.cs
public override int GetHashCode() { #if FEATURE_RANDOMIZED_STRING_HASHING if(HashHelpers.s_UseRandomizedSsortingngHashing) { return InternalMarvin32HashSsortingng(this, this.Length, 0); } #endif // FEATURE_RANDOMIZED_STRING_HASHING unsafe { fixed (char *src = this) { Contract.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'"); Contract.Assert( ((int)src)%4 == 0, "Managed ssortingng should start at 4 bytes boundary"); #if WIN32 int hash1 = (5381<<16) + 5381; #else int hash1 = 5381; #endif int hash2 = hash1; #if WIN32 // 32 bit machines. int* pint = (int *)src; int len = this.Length; while (len > 2) { hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0]; hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1]; pint += 2; len -= 4; } if (len > 0) { hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0]; } #else int c; char *s = src; while ((c = s[0]) != 0) { hash1 = ((hash1 << 5) + hash1) ^ c; c = s[1]; if (c == 0) break; hash2 = ((hash2 << 5) + hash2) ^ c; s += 2; } #endif #if DEBUG // We want to ensure we can change our hash function daily. // This is perfectly fine as long as you don't persist the // value from GetHashCode to disk or count on String A // hashing before string B. Those are bugs in your code. hash1 ^= ThisAssembly.DailyBuildNumber; #endif return hash1 + (hash2 * 1566083941); } } }
C'est peut-être plus que ce que vous aviez négocié, je vais un peu annoter le code:
En examinant le code source (avec la permission de ILSpy ), nous pouvons voir qu’il parcourt la longueur de la chaîne.
// ssortingng [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SecuritySafeCritical] public unsafe override int GetHashCode() { IntPtr arg_0F_0; IntPtr expr_06 = arg_0F_0 = this; if (expr_06 != 0) { arg_0F_0 = (IntPtr)((int)expr_06 + RuntimeHelpers.OffsetToSsortingngData); } char* ptr = arg_0F_0; int num = 352654597; int num2 = num; int* ptr2 = (int*)ptr; for (int i = this.Length; i > 0; i -= 4) { num = ((num << 5) + num + (num >> 27) ^ *ptr2); if (i <= 2) { break; } num2 = ((num2 << 5) + num2 + (num2 >> 27) ^ ptr2[(IntPtr)4 / 4]); ptr2 += (IntPtr)8 / 4; } return num + num2 * 1566083941; }