zoukankan      html  css  js  c++  java
  • C# 高级编程(笔记6)

    第14章  反射

    1.自定义特性(Attribute)

    编译器在遇到代码中某个应用了自定义特性的元素时的处理过程:

    eg:
    
    [StringLength(50, ErrorMessageResourceType = typeof(res), ErrorMessageResourceName = "MAX_USER_NAME_LENGTH")]
    public String UName { get; set; }

    //当C#编译器发现这个属性(property)应用了一个StringLength特性时,首先会把字符串Attribute追加到这个名称的后面,形成一个组合名称StringLengthAttribute,然后在其搜索路径的所有名称空间(即在using语句中提及的名称空间)中搜索有指定名称的类。但要注意,如果用一个特性标记数据项,而该特性的名称以字符串Attribute结尾,编译器就不会把该字符串加到组合名称中,而是不修改该特性名。

    //编译器会找到含有该名称的类,且这个类直接或间接派生自System.Attribute。编译器还认为这个类包含控制特性用法的信息,特别是:

    a.特性可以应用到哪些类型的程序元素上(类、结构、属性和方法等)
    b.它是否可以多次应用到同一个程序元素上
    c.特性在应用到类或接口上时,是否由派生类和接口继承
    d.这个特性有哪些必选和可选参数

    ----如果编译器找不到对应的特性类,或者找到一个这样的特性类,但使用特性的方式与特性类中的信息不匹配,编译器就会产生一个编译错误。

    2.AttributeUsage 特性类

        [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
        public class FieldNameAttribute : Attribute
        {
            public FieldNameAttribute()
            {
            }
        }

    //一个自定义的特性类FieldNameAttribute本身再用一个System.AttributeUsage特性类来标记。AttributeUsage特性类主要用于标识自定义特性可以应用到哪些类型的程序元素上。这些信息由它的第一个参数给出,该参数是必选的,其类型是枚举类型AttributeTargets。

    //AttributeTargets枚举的成员中有两个值不对应于任何程序元素:Assembly和Module,表明该特性可以应用到整个程序集或模块中,而不是应用到代码中的一个元素上,在这种情况下,这个特性可以放在源代码的任何地方,但需要用关键字assembly或module作为前缀

        [assembly: SomeAssemblyAttribute(Parameters)]
        [module: SomeAssemblyAttribute(Parameters)]

    3.System.Type类

    Type类是一个抽象基类,只要实例化一个Type对象,实际上就实例化了Type的一个派生类,Type有与每种数据类型对应的派生类。

    通常,获取指向任何给定类型的Type引用有3种常用方式:

    a.使用C#的typeof运算符
       //获取编译时阶段某一类型的System.Type对象
      //typeof()参数只能是构架中已经定义好了的类型和自定义类型,不能是实例

    Type t
    = typeof(double); b.使用GetType()方法,所有的类都会从System.Object继承这个方法 //获取运行时阶段当前实例的类型
        //GetType()是实例方法
    double d = 10.0; Type t = d.GetType(); c.调用Type类的静态方法GetType() Type t = Type.GetType("System.Double");

    //Type是许多反射功能的入口,它实现许多方法和属性,可以使用Type确定数据的类型,但不能使用它修改该类型

    Type还可以获取在其中定义该类型的程序集的引用:

    Type t = typeof(Vector);
    Assembly ass = new Assembly(t);

    4.Assembly 类

    Assembly类允许访问给定程序集的元数据,它也包含可以加载和执行程序集的方法【假定该程序集是可执行的】。与Type类一样,Assembly类包含非常多的方法与属性。

    在使用Assembly实例做一些工作前,需要把相应的程序集加载到正在运行的进程中。为此,可以使用静态成员Assembly.Load()或Assembly.LoadFrom()。

    a.Assembly.Load()      ---- 该方法的参数是程序集的名称,运行库会在各个位置上搜索该程序集,这些位置包括本地目录和全局程序集缓存
    b.Assembly.LoadFrom()  ---- 该方法的参数是程序集的完整路径名,它不会在其他位置搜索该程序集

    Assembly ass1 = Assembly.Load("SomeAssembly");
    Assembly ass2 = Assembly.LoadFrom(@"C:\My Projects\software\SomeotherAssembly");

    加载完一个程序集后,就可以使用它的各种属性进行查询,如:

    a.查找在程序集中定义的类型
    
    Type[] types = theAssembly.GetTypes();
    foreach(Type t in types)
    {
      ...
    }
    
    
    b.查找自定义特性
    
    //得到指定程序集中所有自定义特性
    Attribute[] attr = Attribute.GetCustomAttributes(theAssembly);
  • 相关阅读:
    1_Maven
    9_项目实战MyShop
    8_文件上传与下载
    使用 selenium 模拟登陆微信公众号平台并且抓取数据
    scrapy框架+scrapy_redis组件的分布式爬虫:爬取某小说网站的所有小说!
    scrapy框架 + redis数据库增量式爬虫 :爬取某小说网站里面的所有小说!
    scrapy框架+redis增量式爬虫: 二进制数据下载>下载某短视频网站里面的短视频的项目工程!
    scrapy框架+redis增量式爬虫: 抓取某短视频里面发布的视频的观看次数、点赞等信息的项目工程!
    在scrapy框架中使用免费的代理ip,解决ip被封禁的问题!!!
    在scrapy框架中使用selenium爬取强国论坛的新闻标题内容+redis增量式
  • 原文地址:https://www.cnblogs.com/notebook2011/p/2970343.html
Copyright © 2011-2022 走看看