2013-05-06 99 views
1

我在這裏有一個基本問題。 我在基類中的抽象方法上有一個屬性。現在,當我在某些派生類中實現/重寫此方法時,我沒有看到爲該派生類方法生成的IL中應用的屬性。 但它一切正常。用於屬性繼承的IL代碼

我在這裏錯過了什麼嗎?我們如何知道編譯器已經標記了由該特定屬性修飾的派生類方法實現?

任何提示?

+1

屬性從不繼承,除非您指示它 – 2013-05-06 13:23:02

+0

什麼NUnit的2.6的TestFixtureTeardown屬性。 X? – 2013-05-06 13:24:13

+0

它在NUnit的文檔中說 - 「TestFixtureTearDown屬性是從任何基類繼承的」。 – 2013-05-06 13:30:09

回答

2

如果您應用在AttributeUsage屬性中設置了Inherited = true的屬性,然後在從具有該屬性的成員繼承的成員上調用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會檢查派生的方法實現是否具有應用的屬性? – 2013-05-06 15:28:12

+0

我只想知道編譯器說這個特定方法將應用這個特定屬性的部分。我將把這個標記爲答案。 – 2013-05-06 15:53:18

+0

@KumarVaibhav那麼,在繼承屬性的情況下,編譯器不會這麼說。 – svick 2013-05-06 16:02:24

1

默認情況下,派生類不會應用屬性,除非您在創建時明確指示它。

AttributesUsage屬性有一個名爲Inherited(布爾類型)的屬性,它告訴您的屬性是否會被派生類繼承。

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

[Custom] 
public class Base { 
} 

public class Sub : Base { 
} 

現在CustomAttribute也被子類應用/繼承。