反射

上图是反射的基本流程

下面是一些反射的用法

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Reflection;
  8 using System.Text;
  9 using System.Threading.Tasks;
 10 using System.Windows.Forms;
 11 
 12 namespace 反射
 13 {
 14     public partial class Form1 : Form
 15     {
 16         public Form1()
 17         {
 18             InitializeComponent();
 19         }
 20         
 21         class MyClass
 22         {
 23             public string m;
 24             public void test() { }
 25             public int MyProperty { get; set; }
 26         }
 27         //反射获取 MyClass 
 28         Type type = typeof(MyClass);
 29         //获取类型名
 30         private void button1_Click(object sender, EventArgs e)
 31         {
 32             textBox1.Text = type.Name;
 33         }
 34         //获取类全名
 35         private void button2_Click(object sender, EventArgs e)
 36         {
 37             textBox1.Text = type.FullName;
 38         }
 39         //获取命名空间
 40         private void button4_Click(object sender, EventArgs e)
 41         {
 42             textBox1.Text = type.Namespace;
 43         }
 44         //获取程序集名
 45         private void button3_Click(object sender, EventArgs e)
 46         {
 47             textBox1.Text = type.Assembly.ToString();
 48         }
 49         //获取模块名
 50         private void button5_Click(object sender, EventArgs e)
 51         {
 52             textBox1.Text = type.Module.ToString();
 53         }
 54         //获取基类名
 55         private void button6_Click(object sender, EventArgs e)
 56         {
 57             textBox1.Text = type.BaseType.ToString();
 58         }
 59         //判断是否是类
 60         private void button7_Click(object sender, EventArgs e)
 61         {
 62             textBox1.Text = type.IsClass.ToString();
 63         }
 64         //获取类的公共成员
 65         private void button8_Click(object sender, EventArgs e)
 66         {
 67             MemberInfo[] arrs = type.GetMembers();
 68             foreach (var item in arrs)
 69             {
 70                 string txt = $"{item.MemberType},{item}\n";
 71                 textBox1.Text = Text;
 72 
 73             }
 74         }
 75 
 76 
 77         //获取当前执行代码的程序集
 78         Assembly assembly = Assembly.GetExecutingAssembly();
 79 
 80         //获取程序集全名
 81         private void button9_Click(object sender, EventArgs e)
 82         {
 83             textBox1.Text = assembly.FullName;
 84         }
 85         //获取程序集的版本
 86         private void button10_Click(object sender, EventArgs e)
 87         {
 88             textBox1.Text = assembly.GetName().Version.ToString();
 89         }
 90         //获取程序集的初始位置
 91         private void button11_Click(object sender, EventArgs e)
 92         {
 93             textBox1.Text = assembly.CodeBase;
 94         }
 95         //获取程序集的位置
 96         private void button12_Click(object sender, EventArgs e)
 97         {
 98             textBox1.Text = assembly.Location;
 99         }
100         //程序集的入口
101         private void button13_Click(object sender, EventArgs e)
102         {
103             textBox1.Text = assembly.EntryPoint.ToString();
104         }
105         //获取程序集下包含的类型
106         private void button14_Click(object sender, EventArgs e)
107         {
108             Type[] types = assembly.GetTypes();
109             string lx = "";
110             foreach (var item in types)
111             {
112                 lx += item.Name+"\n";
113             }
114             textBox1.Text = lx;
115         }
116     }
117 }
反射

 

 反射定义  : 审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。

  System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码

  System.Reflection.Assembly 
  System.Reflection.MemberInfo
  System.Reflection.EventInfo
  System.Reflection.FieldInfo
  System.Reflection.MethodBase
  System.Reflection.ConstructorInfo
  System.Reflection.MethodInfo
  System.Reflection.PropertyInfo
  System.Type   

反射:什么是反射?反射就是在程序运行的过程中,动态的获取类的成员,并对他们进行操作。包括动态调用方法,动态获取,设置属性等。通过特性,也能是想IOC,AOP等功能

特性:特性只有在使用反射的时候才能发挥它最大的作用,通过反射获取到自定义的特性,再根据特性进行操作,例如在通过反射实现ORM的时候,如果一个熟悉设置了不需要ORM的特性,则可以忽略该属性。如果没有反射,那么可以把特性当做注释,它不会对代码的运行造成任何影响。但它和注释的区别在于,它会被编译进程序集,这样才能通过反射获取到这些特性

反射常用的类有Assembly,Activator,Type这几个类

Assembly获取程序集应用,可以通过Load,LoadFile,LoadFrom这几个方法将dll文件加载进当前程序集。如果需要反射的类位于当前程序集,则可以不使用此类

Activator用于动态的创建一个类的实例,通过Assembly加载的程序集,可以获取到它内部的所有的Type,而Activator.Crea  teInstance方法可以为当前对象创建一个实例。(Assembly也有CreateInstance方法用于创建类的实例)。

Type表示一个类型,也可以通过typeof获取例如typeof(int)得到的就是int类型,然后Type对象有很多的方法可以获取对象的成员,包括字段,方法,属性等等对象内部的所有都可以通过Type获得

 

反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。这是一个相对高级的特性,只有那些语言基础非常扎实的开发者才应该使用它。如果能把这句警示时刻放在心里,那么反射机制就会成为一项强大的技术,可以让应用程序做一些几乎不可能做到的事情。

  优点:
            反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;

  缺点:
           1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。      
          2、使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。   至于执行效率的话,还可以,因为它是一种强类型语言,执行效率不错。不过,建议将反射过后,保存进 cache中。

 

尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心:

 

首先是性能:

反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。

 

安全:
使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。

 

成员的内部暴露:

由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化

posted @ 2019-08-06 14:39  进步中的小牛  阅读(108)  评论(0编辑  收藏  举报