Pregunta

I have a basic question here. I have an attribute on an abstract method in a base class. Now when I implement/override this method in some derived class I do not see the attribute being applied in the IL generated for that derived class method. But it all works fine.

Am I missing something here? How do we know that the compiler has marked the derived class method implementation to be decorated by that specific attribute?

Any hints?

¿Fue útil?

Solución

If you apply an attribute that has Inherited = true set in its AttributeUsage attribute, and then call GetCustomAttributes(inherit: true) on a member that inherits from a member with that attribute, then you're going to get that attribute. But you're not going to see anything in the IL of the inheriting member, the compiler doesn't do anything special for it, it's reflection that looks at the base member.

For example with this code:

[AttributeUsage(AttributeTargets.All, Inherited = true)]
class InheritedAttribute : Attribute
{}

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

abstract class Base
{
    [Inherited, NotInherited]
    public abstract void M();
}

class Derived : Base
{
    public override void M()
    {}
}

…

foreach (var type in new[] { typeof(Base), typeof(Derived) })
{
    var method = type.GetMethod("M");

    foreach (var inherit in new[] { true, false })
    {
        var attributes = method.GetCustomAttributes(inherit);

        Console.WriteLine(
            "{0}.{1}, inherit={2}: {3}",
            method.ReflectedType.Name, method.Name, inherit,
            string.Join(", ", attributes.Select(a => a.GetType().Name)));
    }
}

You're going to get this output:

Base.M, inherit=True: NotInheritedAttribute, InheritedAttribute
Base.M, inherit=False: NotInheritedAttribute, InheritedAttribute
Derived.M, inherit=True: InheritedAttribute
Derived.M, inherit=False:

Otros consejos

Attributes are not applied by default on derived classes unless you explicitly instruct it while creation.

The AttributesUsage attribute has a property called Inherited(of type boolean),which tells whether your attribute will be inherited by the derived classes or not.

[AttributeUsage( Inherited = true)]
public class CustomAttribute : Attribute
{
}

[Custom]
public class Base {
}

public class Sub : Base {
}

Now the CustomAttribute is applied/inherited by the sub class as well.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top