diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs index 0c5de0c21006a1..39da6d248bdd2c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs @@ -159,7 +159,6 @@ public override IList GetCustomAttributesData() #region MemberInfo Overrides public override string Name => RuntimeMethodHandle.GetName(this); - public override MemberTypes MemberType => MemberTypes.Constructor; public override Type? DeclaringType => m_reflectedTypeCache.IsGlobal ? null : m_declaringType; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs index 5fc19889cb9e91..1ed8e75c7d7d82 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs @@ -32,12 +32,6 @@ public sealed override bool ContainsGenericParameters public abstract override Type DeclaringType { get; } - public sealed override Type[] GetGenericArguments() - { - // Constructors cannot be generic. Desktop compat dictates that We throw NotSupported rather than returning a 0-length array. - throw new NotSupportedException(); - } - [RequiresUnreferencedCode("Trimming may change method bodies. For example it can change some instructions, remove branches or local variables.")] public sealed override MethodBody GetMethodBody() { diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs index a680267e160719..5a76b17d8d1828 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs @@ -13,6 +13,9 @@ protected ConstructorInfo() { } public override MemberTypes MemberType => MemberTypes.Constructor; + // Constructors are never generic methods, so the generic method arguments are always empty. + public override Type[] GetGenericArguments() => []; + [DebuggerHidden] [DebuggerStepThrough] public object Invoke(object?[]? parameters) => Invoke(BindingFlags.Default, binder: null, parameters: parameters, culture: null); diff --git a/src/libraries/System.Reflection.Context/tests/CustomConstructorInfoTests.cs b/src/libraries/System.Reflection.Context/tests/CustomConstructorInfoTests.cs index ceb4b7ace553f6..9dc2886c0426b3 100644 --- a/src/libraries/System.Reflection.Context/tests/CustomConstructorInfoTests.cs +++ b/src/libraries/System.Reflection.Context/tests/CustomConstructorInfoTests.cs @@ -142,10 +142,10 @@ public void IsDefined_ReturnsFalseForUnattributedConstructor() } [Fact] - public void GetGenericArguments_ThrowsNotSupported() + public void GetGenericArguments_ReturnsEmpty() { - // Constructors don't support GetGenericArguments - Assert.Throws(() => _customConstructor.GetGenericArguments()); + // Constructors are never generic methods, so GetGenericArguments returns an empty array. + Assert.Empty(_customConstructor.GetGenericArguments()); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMethodBodySupported))] diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Method/MethodInvariants.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Method/MethodInvariants.cs index 8e8a1fbdebb6d1..dbde3a65d98f7f 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Method/MethodInvariants.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Method/MethodInvariants.cs @@ -106,7 +106,12 @@ private static void TestConstructorInfoCommonInvariants(this ConstructorInfo c) Assert.False(c.IsConstructedGenericMethod()); Assert.False(c.IsGenericMethod); +#if NET + Assert.Empty(c.GetGenericArguments()); +#else + // On .NET Framework, ConstructorInfo.GetGenericArguments() throws NotSupportedException. Assert.Throws(() => c.GetGenericArguments()); +#endif } private static void TestMethodInfoCommonInvariants(this MethodInfo m) diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 60651667769b39..b84cfd8c2c63aa 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -12309,6 +12309,7 @@ public abstract partial class ConstructorInfo : System.Reflection.MethodBase protected ConstructorInfo() { } public override System.Reflection.MemberTypes MemberType { get { throw null; } } public override bool Equals(object? obj) { throw null; } + public override System.Type[] GetGenericArguments() { throw null; } public override int GetHashCode() { throw null; } public object Invoke(object?[]? parameters) { throw null; } public abstract object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object?[]? parameters, System.Globalization.CultureInfo? culture); diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/ConstructorInfoTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/ConstructorInfoTests.cs index 37498347ac48fe..e8d791d2f8a19f 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/ConstructorInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/ConstructorInfoTests.cs @@ -133,6 +133,19 @@ public void IsPublic() Assert.True(constructors[0].IsPublic); } + [Fact] + public void GetGenericArguments_ReturnsEmptyArray() + { + ConstructorInfo[] constructors = GetConstructors(typeof(ClassWith3Constructors)); + Assert.All(constructors, constructorInfo => Assert.Empty(constructorInfo.GetGenericArguments())); + + ConstructorInfo[] genericTypeConstructors = GetConstructors(typeof(GenericClassWithConstructor)); + Assert.All(genericTypeConstructors, constructorInfo => Assert.Empty(constructorInfo.GetGenericArguments())); + + ConstructorInfo[] openGenericTypeConstructors = GetConstructors(typeof(GenericClassWithConstructor<>)); + Assert.All(openGenericTypeConstructors, constructorInfo => Assert.Empty(constructorInfo.GetGenericArguments())); + } + // Use this class only from the Invoke_StaticConstructorMultipleTimes method public static class ClassWithStaticConstructorThatIsCalledMultipleTimesViaReflection { @@ -159,6 +172,12 @@ public class ConstructorInfoDerived : ConstructorInfoAbstractBase public ConstructorInfoDerived() { } } + public class GenericClassWithConstructor + { + public GenericClassWithConstructor() { } + public GenericClassWithConstructor(T value) { } + } + public class ClassWith3Constructors { public int intValue = 0;