在C#中Attribute是個非常有用的語法,本文不會介紹Attribute的使用方法,如果想了解Attribute的詳細信息請查閱MSDN及網上相關文檔。C#中的Attribute有兩個地方是和繼承相關的,一個地方是AttributeUsageAttribute類中的屬性參數Inherited,另一個地方是Type反射中的GetCustomAttributes方法(包括Type.GetCustomAttributes、MemberInfo.GetCustomAttributes等反射方法)的inherit參數,這兩個與繼承相關的參數都是bool類型,但是代表的含義卻不相同,我們來看看他們分別代表的是什么:
AttributeUsageAttribute類的Inherited屬性參數
AttributeUsage中的屬性參數Inherited指的是繼承鏈中的子類和子類成員是否能繼承在父類和父類成員上聲明的Attribute。我們來看個例子,假如現在我們有兩個類BaseClass和MyClass,其中MyClass繼承於BaseClass,現在我們在BaseClass上聲明一個自定義Attribute叫MyAttribute,代碼如下:
[My] class BaseClass { } class MyClass:BaseClass { }
如果像下面代碼中設置MyAttribute上AttributeUsage的屬性參數Inherited為true,則代表MyAttribute是可以被繼承聲明的,也就是說上面代碼中在父類BaseClass上聲明了MyAttribute后,子類MyClass相當於也聲明了MyAttribute。
[AttributeUsage(AttributeTargets.All, Inherited = true)] class MyAttribute : Attribute { }
如果像下面代碼中設置MyAttribute上AttributeUsage的屬性參數Inherited為false,那么代表MyAttribute是無法被繼承聲明的,也就是說上面代碼中在父類BaseClass上聲明了MyAttribute后,子類MyClass不具有MyAttribute,相當於父類BaseClass聲明了MyAttribute但是子類MyClass沒有聲明MyAttribute。
[AttributeUsage(AttributeTargets.All, Inherited = false)] class MyAttribute : Attribute { }
GetCustomAttributes方法的inherit參數
GetCustomAttributes方法中inherit參數指的是當調用GetCustomAttributes方法時,GetCustomAttributes方法是否搜索子類和子類成員上從父類繼承的Attribute。同樣我們來看個例子,假如現在我們有兩個類BaseClass和MyClass,其中MyClass繼承於BaseClass,現在我們在BaseClass上聲明一個自定義Attribute叫MyAttribute,代碼如下:
[My] class BaseClass { } class MyClass:BaseClass { }
我們在MyAttribute上設置AttributeUsage的屬性參數Inherited為true,那么相當於子類MyClass上也聲明了MyAttribute:
[AttributeUsage(AttributeTargets.All, Inherited = true)] class MyAttribute : Attribute { }
現在如果我們調用構造函數構造一個MyClass對象,然后調用對象的反射方法GetCustomAttributes看是否能在MyClass上找到MyAttribute。如果找到了則在控制台輸出找到了MyAttribute,否則輸出沒有找到。
首先我們調用GetCustomAttributes方法時將參數inherit設置為true。結果控制台顯示:"MyAttribute found!",說明GetCustomAttributes方法成功找到了MyAttribute。
var my = new MyClass(); var myMyAttribute = my.GetType().GetCustomAttributes(typeof(MyAttribute), true); if (myMyAttribute != null && myMyAttribute.Count() > 0) { Console.WriteLine("MyAttribute found!"); } else { Console.WriteLine("MyAttribute not found!"); }
接着我們調用GetCustomAttributes方法時將參數inherit設置為false。這次控制台顯示:"MyAttribute not found!",說明將參數inherit設置為false后GetCustomAttributes方法無法在MyClass上找到MyAttribute了。
var my = new MyClass(); var myMyAttribute = my.GetType().GetCustomAttributes(typeof(MyAttribute), false); if (myMyAttribute != null && myMyAttribute.Count() > 0) { Console.WriteLine("MyAttribute found!"); } else { Console.WriteLine("MyAttribute not found!"); }
這說明GetCustomAttributes方法的inherit參數實際上就是在指示是否去搜索從父類繼承來的Attribute,由於本例中的MyAttribute是聲明在父類BaseClass上的,所以當在子類MyClass的反射中調用GetCustomAttributes(typeof(MyAttribute), false)時,GetCustomAttributes方法將不會去搜索從父類繼承的Attribute,所以在控制台上顯示MyClass上無法找到MyAttribute。但是如果在子類MyClass的反射中調用GetCustomAttributes(typeof(MyAttribute), true),那么GetCustomAttributes方法不光會搜索子類MyClass自己聲明的Attribute還會去搜索從父類BaseClass繼承的Attribute,由於父類BaseClass上聲明了MyAttribute,所以GetCustomAttributes方法在子類MyClass上也能找到MyAttribute,最后在控制台上顯示在MyClass上找到了MyAttribute。如果將MyAttribute聲明在子類MyClass上而不是像本例代碼一樣聲明在父類BaseClass上,那么在調用GetCustomAttributes(typeof(MyAttribute), false)時,就會顯示在MyClass上找到MyAttribute了。
總結一下,我們可以看到AttributeUsageAttribute類的Inherited屬性參數和GetCustomAttributes方法的inherit參數代表的含義是不一樣的。AttributeUsageAttribute類的Inherited屬性代表的是父類或父類成員上聲明的Attribute是否能夠被應用到繼承鏈中子類或子類成員上去。而GetCustomAttributes方法的inherit參數代表的是調用GetCustomAttributes方法時是否去搜索繼承鏈中從父類或父類成員繼承下來的Attribute。