手记

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

  使用特性Attribute可以将描述程序集的信息和描述程序集中任何类型和成员的信息添加到程序集的元数据和IL代码中程序可以在运行时通过反射获取到这些信息

 

  一、通过直接或间接的继承自抽象类System.Attribute可以创建自定义的特性类自定义的特性类必须声明为公共类命名一般使用Attribute结尾以保证可读性自定义特性可以附加到大多数元素声明中也可以使用特性System.AttributeUsage该特性只能用于特性类声明指定该特性所能生效的范围及其它特性特征参数


[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
//其中枚举组合AttributeTargets指定该特性生效的范围默认为All即所有范围
//布尔值Inherited指定应用该特性的成员在派生类中是否会继承该特性默认为true
//布尔值AllowMultiple指定能否为同一个元素指定多个此特性默认为falsepublic class MyselfAttribute : Attribute
{    public string ClassName { get; private set; }    public string Author;        
    public MyselfAttribute(string className)
    {        this.className = className;
    }
}


  其中特性类的构造函数中的参数称为位置参数Positional Parameters类中的其他公共字段和属性称为命名参数Named Parameter 通常情况下将所有必选的参数定义为位置参数将所有可选的参数定义为命名参数特性类和普通类一样可以进行构造函数的重载以适应各种情况下初始化参数的组合使用

 

  二、使用特性时通过方括号[]将特性名称括起来并置于使用该特性的元素声明的上方或前方以指定特性使用时可以省略Attribute后缀根据想要初始化时调用特性类构造函数的不同需要将该构造函数所需的参数即位置参数的值按照顺序传入还可以选择是否指定命名参数的值命名参数的值通过赋值运算符=显式指定


[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…    }
}


   经过编译后在元数据中查看到的类型定义中的特性信息


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代码中查看到的类型定义中的特性信息

 

 

  三、系统预定义的一些常用特性

 

原文作者Minotauros

原文地址https://www.cnblogs.com/minotauros/p/9681037.html

0人推荐
随时随地看视频
慕课网APP