天天看点

C#反射(Reflection)

反射:就是解析过程(把object里面的成员,字段,属性,方法通过类型gettype方法解析出来)

程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。

作用:1.动态创建类的实例(通过assembly程序集 或通过activator创建实例对象  两个是区别最下面有)
	 2.从现有对象中获取类型(通过obj的gettype得到类型,通过类型的GetMethods方法解析出来object里面的成员,
	 字段,方法,特性,出来之后就可以调用或者赋值。)
           

反射的优缺点:

优点:

1、提高程序的灵活性和扩展性。

2、降低耦合性,提高自适应能力。

3、允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

1、性能问题:反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。

2、逻辑问题:对于程序员来说希望在源代码中看到程序的逻辑,但是反射却绕过了源代码的技术,所以反射代码维护起来会更加复杂。

对于反射已经有所了解,那么讲到反射必须要说的2个点要记下来:

1.反射通过obj的gettype得到类型,通过类型的GetMethods方法解析出来object里面的成员,字段,方法,特性,出来之后就可以调用或者赋值。

2.反射通过assembly程序集 或者通过过activator创建实例对象

最后一个反射的例子加深理解:

public class Room
  {
   internal int id;
    public int Id
    {
      get => id;
      set => id = value;
    }
    internal int name;
    public int Name
    {
     get => name;
     set => name = value;
    }
    public void AFunction()
    {
      Console.WriteLine("这是A方法");
    }
  }
  class Program
  {
    static void Main(string[] args)
   {
      //反射的第一个作用:解析成员并调用成员
      //创建room类型的可以直接得到里面的字段  但是object的不可以
      //这个情况下想要调用就用到了反射
     //这个gettype可以看里面的类型和所有成员,
      //把object里面的成员,字段,属性,方法通过类型gettype方法解析出来
      //object room = new Room();  
     //var type=  room.GetType();
    //  foreach (var item in type.GetMethods())
     //  {
     //    //显示所有的成员名字
     //    Console.WriteLine(item.Name);
     //    //找方法的时候就是调用某一个对象的方法  而不是类型的  所以需要把原对象放进去
     //    if (item.Name== "AFunction")
     //    {
     //      item.Invoke(room, new object[] { });
     //    }
     //  }
      //反射的第二个作用:动态创建对象
      //程序集  创建实例对象
      //下面的过程相比上面的来说省了创建对象的步骤  new
     var ass= Assembly.GetExecutingAssembly();
   //gettype获取类型
     var obj=  ass.CreateInstance("reflex.Room");  通过字符串来创建对象
      //通过获取到的类型来解析成员  
     var type= obj.GetType();
     foreach (var item in type.GetMethods())
     {
      Console.WriteLine(item.Name);
    }

   }
}
// Activator.CreateInstance("reflex","类型名")
//Activator 没有写例子,但是跟Assembly用法相似,唯一不同的,就是在动态创建对象的时候,是两个参数(命名空间,类型名)记得引用
           

两个动态创建实例用法的区别:

Activator.CreateInstance(" 程序集名",“程序集名+命名空间”)

assembly(“需要程序集名+命名空间”)