GetCustomAttributes inherit parameter vs AttributeUsage.Inherited

Viewed 2374

Why doesn't GetCustomAttributes(true) return attributes where AttributeUsageAttribute.Inherited = false? There is nothing in the documentation that I can see that says that these two should interact. The following code outputs 0.

class Program
{

    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
    class NotInheritedAttribute : Attribute { }

    [NotInherited]
    class A { }

    class B : A { }

    static void Main(string[] args)
    {
        var attCount = typeof(B).GetCustomAttributes(true).Count();
        Console.WriteLine(attCount);
    }
}
1 Answers

Type.GetCustomAttributes() is an extension method that calls Attribute.GetCustomAttributes() which in turn calls GetCustomAttributes with the parameter inherit set to true. So by default, you are already inheriting when using GetCustomAttributes().

So the only difference is between GetCustomAttributes() and GetCustomAttributes(inherit: false). The latter will disable inheritance for inheritable attributes while the former will just pass those that are inheritable through.

You cannot force attributes that are themselves non-inheritable to be inheritable.

See the following example for a quick summary:

void Main()
{
    typeof(A).GetCustomAttributes().Dump(); // both
    typeof(A).GetCustomAttributes(inherit: false).Dump(); // both

    typeof(B).GetCustomAttributes().Dump(); // inheritable
    typeof(B).GetCustomAttributes(inherit: false).Dump(); // none because inheritance is prevented

    typeof(C).GetCustomAttributes().Dump(); // both
    typeof(C).GetCustomAttributes(inherit: false).Dump(); // both because C comes with its own copies
}

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InheritableExampleAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class NonInheritableExampleAttribute : Attribute { }

[InheritableExample]
[NonInheritableExample]
public class A { }

public class B : A { }

[InheritableExample]
[NonInheritableExample]
public class C : A { }
Related