2013-05-06 4 views
1

У меня есть основной вопрос. У меня есть атрибут абстрактного метода в базовом классе. Теперь, когда я реализую/переопределяю этот метод в каком-то производном классе, я не вижу атрибута, применяемого в IL, сгенерированном для этого метода производного класса. Но все работает отлично.IL код для наследования атрибутов

Я что-то упустил? Как мы узнаем, что компилятор отметил реализацию метода производного класса, который должен быть украшен этим конкретным атрибутом?

Любые подсказки?

+1

Атрибуты никогда не унаследованного, если вы не учите его –

+0

насчет атрибута TestFixtureTeardown из NUnit 2.6. Икс? –

+0

В документации NUnit сказано: «Атрибут TestFixtureTearDown унаследован от любого базового класса». –

ответ

2

Если применить атрибут, который имеет Inherited = true набор в атрибуте AttributeUsage, а затем вызвать GetCustomAttributes(inherit: true) на член, который наследуется от элемента с этим атрибутом, то вы собираетесь получить этот атрибут. Но вы не увидите ничего в IL наследующего члена, компилятор не делает ничего особенного для него, это отражение, которое смотрит на базовый элемент.

Например, с этим кодом:

[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))); 
    } 
} 

Вы собираетесь получить этот результат:

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

Итак, компилятор ничего не делает, но во время выполнения CLR проверяет, применяется ли реализация производного метода или нет? –

+0

Я просто хочу знать, где компилятор говорит, что этот конкретный метод будет иметь этот конкретный атрибут, применяемый к нему. И я собираюсь отметить это как ответ. –

+0

@KumarVaibhav Ну, в случае унаследованных атрибутов компилятор этого не говорит. – svick

1

Атрибуты по умолчанию не применяются к производным классам, если вы явно не инструктируете его при создании.

Атрибут AttributesUsage имеет свойство Inherited (тип boolean), в котором указано, будет ли ваш атрибут наследоваться производными классами или нет.

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

[Custom] 
public class Base { 
} 

public class Sub : Base { 
} 

Теперь CustomAttribute применяется/наследуется класс к югу, а также.

Смежные вопросы