From 6d224ce59c244a42173641aaaa274bfad54090ea Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Sun, 22 Mar 2020 21:31:50 -0400 Subject: [PATCH] [mono] Don't throw inheritance error on interfaces in GetCustomAttrs Looking at https://github.com/dotnet/runtime/issues/7190, the .NET Core behavior here is strange and my changes in https://github.com/dotnet/runtime/commit/0844cb7a6152 with the type checking may have been a mistake. I think this should be fine with the interface special-casing, but if deemed too great a concern I can revert that subset of my old changes. Additionally, if people come up with other scenarios where this might fail, I'll just revert until we can migrate to use a shared CustomAttribute implementation rather than try to play whack-a-mole. --- .../tests/System/Type/TypeTests.Get.cs | 20 +++++++++++++++++++ .../src/System/Reflection/CustomAttribute.cs | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs index 5f19479bc6211..124687962d0f0 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs @@ -91,6 +91,12 @@ public void GetInterface_MixedCaseAmbiguity_ThrowsAmbiguousMatchException() { Assert.Throws(() => typeof(ClassWithMixedCaseInterfaces).GetInterface("mixedinterface", ignoreCase: true)); } + + [Fact] + public void GetCustomAttributes_Interface() + { + Assert.True(typeof(ExampleWithAttribute).GetCustomAttributes(typeof(INameable), inherit: false)[0] is NameableAttribute); + } } public class ClassWithNoInterfaces { } @@ -116,6 +122,20 @@ public interface Interface1 { } public interface Interface2 { } public interface Interface3 { } } + + public interface INameable + { + string Name { get; } + } + + [AttributeUsage (AttributeTargets.All, AllowMultiple=true)] + public class NameableAttribute : Attribute, INameable + { + string INameable.Name => "Nameable"; + } + + [Nameable] + public class ExampleWithAttribute { } } public interface Interface1 { } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs index 3fde27fb5335c..cc141613b5e11 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs @@ -140,7 +140,8 @@ internal static object[] GetCustomAttributes(ICustomAttributeProvider obj, Type throw new ArgumentNullException(nameof(obj)); if (attributeType == null) throw new ArgumentNullException(nameof(attributeType)); - if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute) && attributeType != typeof(CustomAttribute) && attributeType != typeof(object)) + if (!attributeType.IsSubclassOf(typeof(Attribute)) && !attributeType.IsInterface + && attributeType != typeof(Attribute) && attributeType != typeof(CustomAttribute) && attributeType != typeof(object)) throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass + " " + attributeType.FullName); if (attributeType == typeof(CustomAttribute))