反射:就是解析過程(把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(“需要程式集名+命名空間”)