diff --git a/src/System.Private.CoreLib/shared/System/Reflection/MemberInfo.cs b/src/System.Private.CoreLib/shared/System/Reflection/MemberInfo.cs
index 1275cc15a05..d8a7458632b 100644
--- a/src/System.Private.CoreLib/shared/System/Reflection/MemberInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Reflection/MemberInfo.cs
@@ -30,6 +30,8 @@ public virtual Module Module
}
}
+ public virtual bool HasSameMetadataDefinitionAs(MemberInfo other) { throw NotImplemented.ByDesign; }
+
public abstract bool IsDefined(Type attributeType, bool inherit);
public abstract object[] GetCustomAttributes(bool inherit);
public abstract object[] GetCustomAttributes(Type attributeType, bool inherit);
diff --git a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
index ec4d724c524..9ce0ef1c4e6 100644
--- a/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
+++ b/src/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj
@@ -111,6 +111,7 @@
+
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/EcmaFormat/EcmaFormatRuntimeEventInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/EcmaFormat/EcmaFormatRuntimeEventInfo.cs
index d61a80380c1..87820be0acb 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/EcmaFormat/EcmaFormatRuntimeEventInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/EcmaFormat/EcmaFormatRuntimeEventInfo.cs
@@ -113,6 +113,21 @@ public sealed override IEnumerable CustomAttributes
}
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ EcmaFormatRuntimeEventInfo otherEvent = other as EcmaFormatRuntimeEventInfo;
+ if (otherEvent == null)
+ return false;
+ if (!(_reader == otherEvent._reader))
+ return false;
+ if (!(_eventHandle.Equals(otherEvent._eventHandle)))
+ return false;
+ return true;
+ }
+
public sealed override bool Equals(Object obj)
{
EcmaFormatRuntimeEventInfo other = obj as EcmaFormatRuntimeEventInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs
index 032f213e713..f738c4e3ccd 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs
@@ -111,6 +111,23 @@ public sealed override IEnumerable CustomAttributes
}
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ NativeFormatRuntimeEventInfo otherEvent = other as NativeFormatRuntimeEventInfo;
+ if (otherEvent == null)
+ return false;
+ if (!(_reader == otherEvent._reader))
+ return false;
+ if (!(_eventHandle.Equals(otherEvent._eventHandle)))
+ return false;
+ if (!(_definingTypeInfo.Equals(otherEvent._definingTypeInfo)))
+ return false;
+ return true;
+ }
+
public sealed override bool Equals(Object obj)
{
NativeFormatRuntimeEventInfo other = obj as NativeFormatRuntimeEventInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs
index fea20265791..5ba18c687a3 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs
@@ -78,6 +78,8 @@ public sealed override MethodInfo[] GetOtherMethods(bool nonPublic)
throw new PlatformNotSupportedException();
}
+ public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
+
public sealed override Module Module
{
get
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/EcmaFormat/EcmaFormatRuntimeFieldInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/EcmaFormat/EcmaFormatRuntimeFieldInfo.cs
index a058fab710f..3da17059cb9 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/EcmaFormat/EcmaFormatRuntimeFieldInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/EcmaFormat/EcmaFormatRuntimeFieldInfo.cs
@@ -131,6 +131,21 @@ public sealed override String ToString()
}
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ EcmaFormatRuntimeFieldInfo otherField = other as EcmaFormatRuntimeFieldInfo;
+ if (otherField == null)
+ return false;
+ if (!(_reader == otherField._reader))
+ return false;
+ if (!(_fieldHandle.Equals(otherField._fieldHandle)))
+ return false;
+ return true;
+ }
+
public sealed override bool Equals(Object obj)
{
EcmaFormatRuntimeFieldInfo other = obj as EcmaFormatRuntimeFieldInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs
index 97d9d174700..ac03d6b99f4 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs
@@ -112,6 +112,23 @@ public sealed override String ToString()
return (new QTypeDefRefOrSpec(_reader, typeHandle).FormatTypeName(typeContext)) + " " + this.Name;
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ NativeFormatRuntimeFieldInfo otherField = other as NativeFormatRuntimeFieldInfo;
+ if (otherField == null)
+ return false;
+ if (!(_reader == otherField._reader))
+ return false;
+ if (!(_fieldHandle.Equals(otherField._fieldHandle)))
+ return false;
+ if (!(_definingTypeInfo.Equals(otherField._definingTypeInfo)))
+ return false;
+ return true;
+ }
+
public sealed override bool Equals(Object obj)
{
NativeFormatRuntimeFieldInfo other = obj as NativeFormatRuntimeFieldInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs
index 77fa3abf369..3890911371d 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs
@@ -104,6 +104,8 @@ public sealed override object GetValueDirect(TypedReference obj)
return fieldAccessor.GetFieldDirect(obj);
}
+ public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
+
public sealed override Module Module
{
get
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs
new file mode 100644
index 00000000000..4a5aa40d888
--- /dev/null
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection.Runtime.General
+{
+ // This interface's presence on a MemberInfo testates that
+ //
+ // 1. The MemberInfo implemented by Reflection.Core
+ // 2. Is to be lumped into the "no metadata token" group for the purposes
+ // of the HasSameMetadataDefinitionAs() api.
+ //
+ internal interface IRuntimeMemberInfoWithNoMetadataDefinition
+ {
+ }
+}
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/EcmaFormat/EcmaFormatMethodCommon.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/EcmaFormat/EcmaFormatMethodCommon.cs
index b1d9a2d972f..8249cc3c78c 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/EcmaFormat/EcmaFormatMethodCommon.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/EcmaFormat/EcmaFormatMethodCommon.cs
@@ -312,6 +312,15 @@ public MethodDefinitionHandle MethodHandle
}
}
+ public bool HasSameMetadataDefinitionAs(EcmaFormatMethodCommon other)
+ {
+ if (!(_reader == other._reader))
+ return false;
+ if (!(_methodHandle.Equals(other._methodHandle)))
+ return false;
+ return true;
+ }
+
public override bool Equals(Object obj)
{
if (!(obj is EcmaFormatMethodCommon))
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/IRuntimeMethodCommon.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/IRuntimeMethodCommon.cs
index 01d872c67ff..cba2855425c 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/IRuntimeMethodCommon.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/IRuntimeMethodCommon.cs
@@ -50,6 +50,8 @@ internal interface IRuntimeMethodCommon where TRuntimeMeth
bool IsGenericMethodDefinition { get; }
+ bool HasSameMetadataDefinitionAs(TRuntimeMethodCommon other);
+
TRuntimeMethodCommon RuntimeMethodCommonOfUninstantiatedMethod { get; }
RuntimeTypeInfo[] GetGenericTypeParametersWithSpecifiedOwningMethod(RuntimeNamedMethodInfo owningMethod);
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs
index 325eb1f7888..e44cf627bd8 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs
@@ -311,6 +311,17 @@ public MethodHandle MethodHandle
}
}
+ public bool HasSameMetadataDefinitionAs(NativeFormatMethodCommon other)
+ {
+ if (!(_reader == other._reader))
+ return false;
+ if (!(_methodHandle.Equals(other._methodHandle)))
+ return false;
+ if (!(_definingTypeInfo.Equals(other._definingTypeInfo)))
+ return false;
+ return true;
+ }
+
public override bool Equals(Object obj)
{
if (!(obj is NativeFormatMethodCommon))
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs
index 9fd1adf7711..e9f59b1febb 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs
@@ -30,6 +30,15 @@ private RuntimeCLSIDNullaryConstructorInfo(RuntimeCLSIDTypeInfo declaringType)
public sealed override IEnumerable CustomAttributes => Empty.Enumerable;
public sealed override Type DeclaringType => _declaringType;
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ // This logic is written to match CoreCLR's behavior.
+ return other is RuntimeCLSIDNullaryConstructorInfo;
+ }
+
public sealed override bool Equals(object obj)
{
RuntimeCLSIDNullaryConstructorInfo other = obj as RuntimeCLSIDNullaryConstructorInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs
index ec7bab4a010..cbab726c4ae 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs
@@ -49,6 +49,11 @@ public sealed override IEnumerable CustomAttributes
}
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ return _genericMethodDefinition.HasSameMetadataDefinitionAs(other);
+ }
+
public sealed override bool Equals(Object obj)
{
RuntimeConstructedGenericMethodInfo other = obj as RuntimeConstructedGenericMethodInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs
index 25c47e17a18..a54967600d3 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs
@@ -79,6 +79,8 @@ public sealed override ParameterInfo[] GetParametersNoCopy()
return RuntimeParameters;
}
+ public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
+
public abstract override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture);
[DebuggerGuidedStepThrough]
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs
index bb67ebe8bb2..1423d21f7ea 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs
@@ -29,6 +29,7 @@ private RuntimeDummyMethodInfo() { }
public sealed override bool IsConstructedGenericMethod { get { throw NotImplemented.ByDesign; } }
public sealed override bool IsGenericMethod { get { throw NotImplemented.ByDesign; } }
public sealed override bool IsGenericMethodDefinition { get { throw NotImplemented.ByDesign; } }
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other) { throw NotImplemented.ByDesign; }
public sealed override MethodImplAttributes MethodImplementationFlags { get { throw NotImplemented.ByDesign; } }
public sealed override Module Module { get { throw NotImplemented.ByDesign; } }
public sealed override MethodBase MetadataDefinitionMethod { get { throw NotImplemented.ByDesign; } }
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs
index 1b31a5cd59a..bf5ef0cd4e5 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs
@@ -185,6 +185,8 @@ public sealed override ParameterInfo[] GetParametersNoCopy()
return RuntimeParameters;
}
+ public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other);
+
[DebuggerGuidedStepThroughAttribute]
public sealed override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
{
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs
index 3cbed32156d..03beae11c2a 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs
@@ -189,6 +189,23 @@ public sealed override String ToString()
return ComputeToString(this);
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ // Do not rewrite as a call to IsConstructedGenericMethod - we haven't yet established that "other" is a runtime-implemented member yet!
+ RuntimeConstructedGenericMethodInfo otherConstructedGenericMethod = other as RuntimeConstructedGenericMethodInfo;
+ if (otherConstructedGenericMethod != null)
+ other = otherConstructedGenericMethod.GetGenericMethodDefinition();
+
+ RuntimeNamedMethodInfo otherMethod = other as RuntimeNamedMethodInfo;
+ if (otherMethod == null)
+ return false;
+
+ return _common.HasSameMetadataDefinitionAs(otherMethod._common);
+ }
+
public sealed override bool Equals(Object obj)
{
RuntimeNamedMethodInfo other = obj as RuntimeNamedMethodInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs
index 37eeb57a852..0dbb40e002d 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs
@@ -145,6 +145,17 @@ public sealed override int MetadataToken
}
}
+ public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other)
+ {
+ if (other == null)
+ throw new ArgumentNullException(nameof(other));
+
+ RuntimePlainConstructorInfo otherConstructor = other as RuntimePlainConstructorInfo;
+ if (otherConstructor == null)
+ return false;
+ return _common.HasSameMetadataDefinitionAs(otherConstructor._common);
+ }
+
public sealed override bool Equals(Object obj)
{
RuntimePlainConstructorInfo other = obj as RuntimePlainConstructorInfo;
diff --git a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs
index 8cdced0cc75..202a3447f57 100644
--- a/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs
+++ b/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs
@@ -18,10 +18,12 @@ namespace System.Reflection.Runtime.MethodInfos
//
// The runtime's implementation of constructors exposed on array types.
//
- internal sealed partial class RuntimeSyntheticConstructorInfo : RuntimeConstructorInfo
+ internal sealed partial class RuntimeSyntheticConstructorInfo : RuntimeConstructorInfo, IRuntimeMemberInfoWithNoMetadataDefinition
{
private RuntimeSyntheticConstructorInfo(SyntheticMethodId syntheticMethodId, RuntimeTypeInfo declaringType, RuntimeTypeInfo[] runtimeParameterTypes, InvokerOptions options, Func