天天看點

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(“需要程式集名+命名空間”)