详解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

本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。

相关文章
相关标签/搜索