From: Peter Smulovics Date: Thu, 20 Apr 2017 22:46:39 +0000 (-0400) Subject: Fixing Delegate's hash code's distribution (dotnet/coreclr#11019) X-Git-Tag: submit/tizen/20210909.063632~11030^2~7179 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=673ed336f00ba6ba5ce37e01792934c39b7641c3;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fixing Delegate's hash code's distribution (dotnet/coreclr#11019) Delegate's GetHashCode just returns the hash code of the delegate type. For a scenario where delegates are used as keys in a dictionary, this leads to obvious performance problems. We should look at coming up with a better GetHashCode that properly factors in the target object and method, in all of the various forms a delegate can take. Commit migrated from https://github.com/dotnet/coreclr/commit/eb2d44e166f05e1d3da06925c39289bd2c4446a8 --- diff --git a/src/coreclr/src/mscorlib/src/System/Delegate.cs b/src/coreclr/src/mscorlib/src/System/Delegate.cs index de0ff65..75ec57a 100644 --- a/src/coreclr/src/mscorlib/src/System/Delegate.cs +++ b/src/coreclr/src/mscorlib/src/System/Delegate.cs @@ -179,7 +179,10 @@ namespace System else return unchecked((int)((long)this._methodPtrAux)); */ - return GetType().GetHashCode(); + if (_methodPtrAux.IsNull()) + return ( _target != null ? RuntimeHelpers.GetHashCode(_target) * 33 : 0) + GetType().GetHashCode(); + else + return GetType().GetHashCode(); } public static Delegate Combine(Delegate a, Delegate b) diff --git a/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs b/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs index f2c5c51..05ba362 100644 --- a/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs +++ b/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs @@ -218,7 +218,7 @@ namespace DelegateTest { bool retVal = true; - TestLibrary.TestFramework.BeginScenario("PosTest7: Use the different instance's same instance method to create two delegate which delegate object is the same,their hashcode is equal"); + TestLibrary.TestFramework.BeginScenario("PosTest7: Use the different instance's same instance method to create two delegate which delegate object is the same, their hashcode is different"); try { @@ -226,7 +226,7 @@ namespace DelegateTest booldelegate workDelegate = new booldelegate(new TestClass(1).StartWork_Bool); booldelegate workDelegate1 = new booldelegate(new TestClass1(2).StartWork_Bool ); - if (workDelegate.GetHashCode()!=workDelegate1.GetHashCode()) + if (workDelegate.GetHashCode()==workDelegate1.GetHashCode()) { TestLibrary.TestFramework.LogError("013", "HashCode is not excepted "); retVal = false;