diff options
author | Buyaa Namnan <bunamnan@microsoft.com> | 2022-11-12 06:22:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-12 06:22:24 +0300 |
commit | 52eed7dc3912594631dfecca56da3057bec52ba6 (patch) | |
tree | 172e58604b911ae38287f11db6d0724ea4dc8413 | |
parent | 43272d63c80f1cf6247fec62c2e189aa763f63a7 (diff) |
Fix Equals in hot reload scenario (#78249)
* Fix Equals in hot reload scenario
Co-authored-by: Steve Harter <steveharter@users.noreply.github.com>
5 files changed, 54 insertions, 5 deletions
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdFieldInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdFieldInfo.cs index 8f241f4d8b6..eba04c404f4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdFieldInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdFieldInfo.cs @@ -46,7 +46,11 @@ namespace System.Reflection public override bool Equals(object? obj) => ReferenceEquals(this, obj) || - (MetadataUpdater.IsSupported && CacheEquals(obj)); + (MetadataUpdater.IsSupported && + obj is MdFieldInfo fi && + fi.m_tkField == m_tkField && + ReferenceEquals(fi.m_declaringType, m_declaringType) && + ReferenceEquals(fi.m_reflectedTypeCache.GetRuntimeType(), m_reflectedTypeCache.GetRuntimeType())); public override int GetHashCode() => HashCode.Combine(m_tkField.GetHashCode(), m_declaringType.GetUnderlyingNativeHandle().GetHashCode()); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs index 8ff2878596d..58de30a1976 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs @@ -118,7 +118,10 @@ namespace System.Reflection public override bool Equals(object? obj) => ReferenceEquals(this, obj) || - (MetadataUpdater.IsSupported && CacheEquals(obj)); + (MetadataUpdater.IsSupported && + obj is RtFieldInfo fi && + fi.m_fieldHandle == m_fieldHandle && + ReferenceEquals(fi.m_reflectedTypeCache.GetRuntimeType(), m_reflectedTypeCache.GetRuntimeType())); public override int GetHashCode() => HashCode.Combine(m_fieldHandle.GetHashCode(), m_declaringType.GetUnderlyingNativeHandle().GetHashCode()); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs index 09adb05fc28..943c4d6ccd0 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs @@ -71,7 +71,11 @@ namespace System.Reflection public override bool Equals(object? obj) => ReferenceEquals(this, obj) || - (MetadataUpdater.IsSupported && CacheEquals(obj)); + (MetadataUpdater.IsSupported && + obj is RuntimeEventInfo ei && + ei.m_token == m_token && + ReferenceEquals(ei.m_declaringType, m_declaringType) && + ReferenceEquals(ei.m_reflectedTypeCache.GetRuntimeType(), m_reflectedTypeCache.GetRuntimeType())); public override int GetHashCode() => HashCode.Combine(m_token.GetHashCode(), m_declaringType.GetUnderlyingNativeHandle().GetHashCode()); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs index b844b6eaa0d..a6b97f36353 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs @@ -182,7 +182,10 @@ namespace System.Reflection public override bool Equals(object? obj) => ReferenceEquals(this, obj) || - (MetadataUpdater.IsSupported && CacheEquals(obj)); + (MetadataUpdater.IsSupported && obj is RuntimePropertyInfo rpi && + rpi.m_token == m_token && + ReferenceEquals(rpi.m_declaringType, m_declaringType) && + ReferenceEquals(rpi.m_reflectedTypeCache.GetRuntimeType(), m_reflectedTypeCache.GetRuntimeType())); public override int GetHashCode() => HashCode.Combine(m_token.GetHashCode(), m_declaringType.GetUnderlyingNativeHandle().GetHashCode()); diff --git a/src/libraries/System.Runtime/tests/System/Reflection/ReflectionCacheTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/ReflectionCacheTests.cs index 40ce2360032..a5922112c1d 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/ReflectionCacheTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/ReflectionCacheTests.cs @@ -7,8 +7,18 @@ using Xunit; namespace System.Reflection.Tests { + public class A + { + public string P { get; set; } + public int F; +#pragma warning disable CS0067 + public event EventHandler E; +#pragma warning restore CS0067 + public void M() { } + } + [Collection(nameof(DisableParallelization))] - public class ReflectionCacheTests + public class ReflectionCacheTests : A { private static bool IsMetadataUpdateAndRemoteExecutorSupported => PlatformDetection.IsMetadataUpdateSupported && RemoteExecutor.IsSupported; @@ -47,6 +57,12 @@ namespace System.Reflection.Tests AssertSameEqualAndHashCodeEqual(fi1, fi2); AssertSameEqualAndHashCodeEqual(ei1, ei2); AssertSameEqualAndHashCodeEqual(ci1, ci2); + + PropertyInfo parentProperty = typeof(A).GetProperty("P"); + PropertyInfo childProperty = s_type.GetProperty("P"); + Assert.NotNull(parentProperty); + Assert.NotNull(childProperty); + Assert.NotEqual(parentProperty, childProperty); } void AssertSameEqualAndHashCodeEqual(object o1, object o2) @@ -87,6 +103,20 @@ namespace System.Reflection.Tests EventInfo ei1 = s_type.GetEvent(nameof(Event1)); ConstructorInfo ci1 = s_type.GetConstructor(Type.EmptyTypes); + PropertyInfo parentProperty = typeof(A).GetProperty("P"); + PropertyInfo childProperty = s_type.GetProperty("P"); + FieldInfo parentField = typeof(A).GetField("F"); + FieldInfo childField = s_type.GetField("F"); + MethodInfo parentMethod = typeof(A).GetMethod("M"); + MethodInfo childMethod = s_type.GetMethod("M"); + EventInfo parentEvent = typeof(A).GetEvent("E"); + EventInfo childEvent = s_type.GetEvent("E"); + + Assert.NotEqual(parentProperty, childProperty); + Assert.NotEqual(parentField, childField); + Assert.NotEqual(parentMethod, childMethod); + Assert.NotEqual(parentEvent, childEvent); + clearCache(new[] { typeof(ReflectionCacheTests) }); MethodInfo mi2 = s_type.GetMethod(nameof(Method)); @@ -95,6 +125,11 @@ namespace System.Reflection.Tests EventInfo ei2 = s_type.GetEvent(nameof(Event1)); ConstructorInfo ci2 = s_type.GetConstructor(Type.EmptyTypes); + Assert.NotEqual(parentProperty, childProperty); + Assert.NotEqual(parentField, childField); + Assert.NotEqual(parentMethod, childMethod); + Assert.NotEqual(parentEvent, childEvent); + AssertNotSameSameButEqualAndHashCodeEqual(mi1, mi2); AssertNotSameSameButEqualAndHashCodeEqual(pi1, pi2); AssertNotSameSameButEqualAndHashCodeEqual(fi1, fi2); |