C#语言基础-15 反射

反射
  自定义特性允许把自定义元数据与程序元素关联起来,这些元数据是在编译过程中创建的,并嵌入到程序集中。反射描述了在运行过程中检查和处理程序元素的功能
  反射允许:枚举类型成员、实例化新对象、执行对象成员、查找类型信息、查找程序集信息、检查类型的自定义特性、创建和编辑新程序集。

自定义特性

  编写自定义特性
  自定义特性类直接或间接的派生自System.Attribute类。特性类一般以Attribute结尾。在vs中创建自定义特性时,名称会自动追加Attribute,在使用时不需要写完整名称,如TestAttribute在使用时写Test或者TestAttribute都可以,匹配的都是TestAttribute类。当同时定义TestAttribute和TestAttributeAttribute时,使用TestAttribute时,编译器会报错,因为不知道引用的是哪个特性类。

    特性类还需要指定:
        特性可以应用到哪些类型的程序元素上(类、结构、属性和方法等)、
        是否可以多次应用到同一个程序元素上、
        应用到类或接口上时,是否由派生类和接口继承、
        特性包含哪些必选和可选参数等。

  指定AttributeUsage特性
    该特性只能应用在其他特性上,用来标示自定义特性可以应用到哪些类型的程序元素上。该参数是必选的AttributeUsage特性的两个参数:都是可选的
        AllowMultiple:标示是否可以多次应用到同一项上。默认值false
        Inherited:标示应用到类或接口上时,是否由派生类和接口继承。应用到方法或属相上时,是都可以重写版本。默认值true 

  指定特性参数
    编译器会检查传递给特性的参数,并查找该特性中带这些参数的构造函数。如果找不到就会抛出异常。

  指定特性的可选参数
    可以通过特性类中的公共属性或字段实现把可选参数添加到特性中。

    [Test("", Num = 12)]//错误的,标示了只能应用于方法
    class Program
    {
        [Test("", Num = 12)]
        static void Main(string[] args)
        {
            Person p = new Person() { Name = "Liu" };

            Console.ReadKey();
        }
    }
    //AttributeTargets.Method表示特性只能应用于方法,AllowMultiple=true表示可以引用1次或多次
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    class TestAttribute : Attribute
    {
        public int Num { get; set; }//使用公共属性接受可选参数
        private string Show { get; set; }
        public TestAttribute(string show, string show2 = "")//使用构造函数参数接受必填参数
        {
            Show = show;
        }
    } 

反射
   通过System.Type类可以访问关于任何数据类型的信息。通过System.Reflection.Assembly类可以访问给定程序集的相关信息。
   System.Type类
      Type类是一个抽象的基类。实例化Type对象时,实际上是实例化了Type的一个派生类。
      获取给定类型的Type引用有3中方式
         typeof运算符
         GetType()方法。所有类都会从System.Object继承这个方法
         使用Type类的静态GetType()方法。

            Person p = new Person() { Name = "Liu" };
            Type type = typeof(Person);
            type = p.GetType();
            type = Type.GetType("Person");   

      Type的属性
        获取包含与类相关的各种名称的字符串。

        获取Type对象的引用,这些引用表示相关的类。

        表示Type对象的一些属性。如IsClass、IsArray、IsEnum、IsAbstract、IsSealed、IsPublic等

            Person p = new Person() { Name = "Liu" };
            Type type = typeof(Person);
            var n = type.Name;//Person
            var fn = type.FullName;//ConsoleApp1.Person
            var ns = type.Namespace;//ConsoleApp1

            Type bt = type.BaseType;
            Type ut = type.UnderlyingSystemType;

            bool isclass = type.IsClass;//true
            bool isenum = type.IsEnum;//false
            bool isarray = type.IsArray;//false
            bool ispublic = type.IsPublic;//false
            bool isabstract = type.IsAbstract;//false

      Type的方法
        大多数方法用于获取对应数据类型的成员信息:构造函数、属性、方法和事件等。 

   System.Reflection.Assembly类
      Assembly类允许访问给定程序集的元数据,还包含可以加载和执行程序集的方法。
      使用Assembly实例时,需要先把相应的程序集加载到正在运行的进程中。可以使用静态成员Assembly.Load()或Assembly.LoadFrom()。
        Assembly.Load()的参数是程序集的名称。运行库会在各个位置搜索该程序集,包括本地目录和全局程序集缓存。
        Assembly.LoadFrom()的参数是程序集的完成整路径名。

            Assembly assembly = Assembly.Load("Newtonsoft.Json");
            Assembly assembly2 = Assembly.LoadFrom(@"E:\LiuXiansheng\ConsoleApp1\bin\Debug\Newtonsoft.Json");

      获取在程序集中定义的类型的详细信息
         Assembly.GetTypes()方法可以返回程序集中定义的所有类型的详细信息的System.Type引用数组。

      获取自定义特性的详细信息
        Assembly.GetCustomAttributes()方法可以获取程序集或类型中关联的自定义特性。

posted @ 2020-04-08 22:34  该昵称有误  阅读(120)  评论(0)    收藏  举报