詳解C#特性和反射(一)

  使用特性(Attribute)能夠將描述程序集的信息和描述程序集中任何類型和成員的信息添加到程序集的元數據和IL代碼中,程序能夠在運行時經過反射獲取到這些信息;ide

 

  1、經過直接或間接的繼承自抽象類System.Attribute能夠建立自定義的特性類,自定義的特性類必須聲明爲公共類,命名通常使用Attribute結尾以保證可讀性,自定義特性能夠附加到大多數元素聲明中,也可使用特性System.AttributeUsage(該特性只能用於特性類聲明)指定該特性所能生效的範圍及其它特性特徵參數:函數

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
//其中,枚舉組合AttributeTargets指定該特性生效的範圍,默認爲All即全部範圍;
//布爾值Inherited指定應用該特性的成員在派生類中是否會繼承該特性,默認爲true;
//布爾值AllowMultiple指定可否爲同一個元素指定多個此特性,默認爲false
public class MyselfAttribute : Attribute { public string ClassName { get; private set; } public string Author; public MyselfAttribute(string className) { this.className = className; } }

  其中特性類的構造函數中的參數稱爲位置參數(Positional Parameters),類中的其餘公共字段和屬性稱爲命名參數(Named Parameter), 一般狀況下,將全部必選的參數定義爲位置參數,將全部可選的參數定義爲命名參數;特性類和普通類同樣能夠進行構造函數的重載以適應各類狀況下初始化參數的組合使用;this

 

  2、使用特性時,經過方括號[]將特性名稱括起來,並置於使用該特性的元素聲明的上方或前方以指定特性,使用時能夠省略Attribute後綴,根據想要初始化時調用特性類構造函數的不一樣,須要將該構造函數所需的參數(即位置參數)的值按照順序傳入,還能夠選擇是否指定命名參數的值,命名參數的值經過賦值運算符=顯式指定:spa

[Myself("MyClass", Author = "Me")]
//這個聲明在概念上等效於: //MyselfAttribute myselfObj = new MyselfAttribute("MyClass"); //myselfObj.Author = "Me"; //[Myself("MyClass", Author = "You")] //特性Myself能夠對同一元素指定屢次 //也能夠將多個特性合併在一個方括號裏: //[Myself("MyClass", Author = "Me"), Myself("MyClass", Author = "You")] public class MyClass { public void MyFunc([Myself("MyParameter")]int myNum) //在方法參數列表中給參數指定特性 { //do… } }

   通過編譯後,在元數據中查看到的類型定義中的特性信息:code

TypeDef #1 (02000002)
-------------------------------------------------------
    TypDefName: MyClass  (02000002)
    Flags     : [Public] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100001)
    Extends   : 01000013 [TypeRef] System.Object
    Method #1 (06000001) 
    -------------------------------------------------------
        MethodName: MyFunc (06000001)
        Flags     : [Public] [Virtual] [HideBySig] [NewSlot]  (000001c6)
        RVA       : 0x00002050
        ImplFlags : [IL] [Managed]  (00000000)
        CallCnvntn: [DEFAULT]
        hasThis 
        ReturnType: Void
        1 Arguments
            Argument #1:  I4
        1 Parameters
            (1) ParamToken : (08000001) Name : myNum flags: [none] (00000000)
            CustomAttribute #1 (0c000003)
            -------------------------------------------------------
                CustomAttribute Type: 06000009
                CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String)
                Length: 16
                Value : 01 00 0b 4d 79 50 61 72  61 6d 65 74 65 72 00 00 >   MyParameter  <
                ctor args: ("MyParameter")


    Method #2 (06000002) 
    -------------------------------------------------------
        MethodName: .ctor (06000002)
        Flags     : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor]  (00001886)
        RVA       : 0x0000205a
        ImplFlags : [IL] [Managed]  (00000000)
        CallCnvntn: [DEFAULT]
        hasThis 
        ReturnType: Void
        No arguments.

    CustomAttribute #1 (0c000015)
    -------------------------------------------------------
        CustomAttribute Type: 06000009
        CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String)
        Length: 24
        Value : 01 00 07 4d 79 43 6c 61  73 73 01 00 54 0e 06 41 >   MyClass  T  A<
                      : 75 74 68 6f 72 02 4d 65                          >uthor Me        <
        ctor args: ("MyClass")

  在IL代碼中查看到的類型定義中的特性信息:blog

 

 

  3、系統預約義的一些經常使用特性:繼承

 

   4、特性一般配合反射起做用,在指定的時機經過反射得到自定義特性並對其進行操做,具體內容在下一章中介紹;ip

 


若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的承認是我寫做的最大動力!ci

做者:Minotauros
出處:https://www.cnblogs.com/minotauros/get

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。

相關文章
相關標籤/搜索