C#高階-反射

概念

反射機制是使程序具有動態(tài)特性的非常關(guān)鍵的一種機制

需求1:根據(jù)指定的類名,類字段名和所對應(yīng)的數(shù)據(jù),得到該類的實例。

需求2:根據(jù)指定的裝箱對象 獲取其屬性值或者調(diào)用其方法

需求3:獲取未來會產(chǎn)生的程序集 并使用其中的類

讓我們可以于運行時加載、探知、使用編譯期間完全未知的classes。換句話說,程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods1。

反射需要的類

反射用到的命名空間:

???System.Reflection

???System.Type

???System.Reflection.Assembly

???(1)使用Assembly定義和加載程序集,加載在程序集清單中列出模塊,以及從此程序集中查找類型并創(chuàng)建該類型的實例。 ???

? ?(2)使用Type這個類可以訪問任何給定數(shù)據(jù)類型的信息。

???(3)使用ConstructorInfo了解構(gòu)造函數(shù)的名稱、參數(shù)、訪問修飾符(如pulic 或private)和實現(xiàn)詳細信息(如abstract或virtual)等。

???(4)使用MethodInfo了解方法的名稱、返回類型、參數(shù)、訪問修飾符(如pulic 或private)和實現(xiàn)詳細信息(如abstract或virtual)等。

???(5)使用FiedInfo了解字段的名稱、訪問修飾符(如public或private)和實現(xiàn)詳細信息(如static)等,并獲取或設(shè)置字段值。

???(6)使用PropertyInfo了解屬性的名稱、數(shù)據(jù)類型、聲明類型、反射類型和只讀或可寫狀態(tài)等,獲取或設(shè)置屬性值。

System.Type類:

???System.Type 類對于反射起著核心的作用。但它是一個抽象的基類,Type有與每種數(shù)據(jù)類型對應(yīng)的派生類,我們使用這個派生類的對象的方法、字段、屬性來查找有關(guān)該類型的所有信息。

???獲取給定類型的Type引用有3種常用方式:

???●使用 C# typeof 運算符。已知類型

???????Type t = typeof(string);

???●使用對象GetType()方法。 已知對象

???????string s = "grayworm";

???????Type t = s.GetType();

???●還可以調(diào)用Type類的靜態(tài)方法GetType()。已知類名

???????Type t = Type.GetType("System.String");

反射生成的對象

1.用Type構(gòu)建對象

用構(gòu)造函數(shù)動態(tài)生成對象:

既然有反射 那就有“正射”

對比一下:

有一個class Test ?有無參構(gòu)造方法

獲取實例的比較:

“正” :由類名直接使用關(guān)鍵字new來獲得 語法:new Test()

反射:未知類名 運行時獲得類型名:例如:Type?type?=?Type.GetType("Test");

???Object o = type.GetConstructor (new Type[]{}).Invoke (null);

??當然參數(shù)也可以由配置文件獲得

以上調(diào)用無參構(gòu)造 帶參的構(gòu)造怎么調(diào)用呢?

2.用Activator生成對象:

???? ?Type t = typeof(NewClassw);

???????//構(gòu)造函數(shù)的參數(shù)

???????object[] obj = new object[2] { "實參1", "實參2" }; ??

???????//用Activator的CreateInstance靜態(tài)方法,生成新對象

???????object o = Activator.CreateInstance(t,obj);

3.Assembly生成對象:

Assembly assembly = Assembly.Load ("ReflectTest");

Object obj = assembly.CreateInstance ("ReflectTest.Wood");

反射獲取字段值

一般用于已知對象時使用

同樣用正反來做對比:

已知對象MyClass obj

對象內(nèi)有name這個字段

正:

obj.name = "xxx"即可設(shè)置該對象的值

obj.name即可獲得該對象的值

反射:

//獲取類的描述對象

Type t = obj.GetType();

//取得字段描述對象

FieldInfo fi = t.GetField("name");

//獲取或設(shè)置字段值

fi.SetValue(obj, "k001");

fi.GetValue(obj);

一般在C#中以屬性替代字段

//獲取類的描述對象

Type t = obj.GetType();

//取得屬性描述對象

PropertyInfo pi1 = t.GetProperty("Name");

//獲取或設(shè)置屬性值

pi1.SetValue(obj, "k001",null);

pi1.GetValue(obj,null);

反射執(zhí)行方法

一般用于對象、方法名、參數(shù)類型已知

對象:obj?

方法名:methodName

參數(shù)類型 String int

正:

直接給予參數(shù)調(diào)用:obj.methodName("實參1",實參2(int))

反射:

//獲取類的描述對象

Type t = obj.GetType();

//取得方法描述對象

MethodInfo mi = t.GetMethod("show");

//調(diào)用方法

mi.Invoke(obj, "實參1",實參2(int));

參數(shù)可以換成數(shù)組

動態(tài)載入程序集

System.Reflection.Assembly類

????Assembly類可以獲得程序集的信息,也可以動態(tài)的加載程序集,以及在程序集中查找類型信息,并創(chuàng)建該類型的實例。

???使用Assembly類可以降低程序集之間的耦合,有利于軟件結(jié)構(gòu)的合理化。


???通過程序集名稱返回Assembly對象

???????Assembly ass = Assembly.Load("ClassLibrary831");

???通過DLL文件名稱返回Assembly對象

???????Assembly ass = Assembly.LoadFrom("ClassLibrary831.dll");

???通過Assembly獲取程序集中類

???????Type t = ass.GetType("ClassLibrary831.NewClass"); ??//參數(shù)必須是類的全名

???通過Assembly獲取程序集中所有的類

???????Type[] t = ass.GetTypes();


???//通過程序集的名稱反射

???Assembly ass = Assembly.Load("ClassLibrary831");

???Type t = ass.GetType("ClassLibrary831.NewClass");

???object o = Activator.CreateInstance(t, "", "");

???MethodInfo mi = t.GetMethod("show");

???mi.Invoke(o, null);

??//通過DLL文件全名反射其中的所有類型

???Assembly assembly = Assembly.LoadFrom("xxx.dll的路徑");

???Type[] aa = a.GetTypes();

???foreach(Type t in aa)

???{

???????if(t.FullName == "a.b.c")

???????{

???????????object o = Activator.CreateInstance(t);

???????}

???}

小結(jié)

反射屬于面向?qū)ο蟮膭討B(tài)補充

讓C#的面向?qū)ο笞龅?所見即所得"

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是反射 反射 [Reflection]:是.Net中獲取運行時類型信息的方式,.Net的應(yīng)用程序共有三個部分:...
    passiony閱讀 554評論 0 3
  • 轉(zhuǎn)自博客園 反射是.NET中的重要機制,通過反射,可以在運行時獲得程序或程序集中每一個類型(包括類、結(jié)構(gòu)、委托、接...
    極客詩人閱讀 993評論 0 0
  • 反射反射,程序員的快樂 這句話想必大家都經(jīng)常聽過,基本上在絕大多數(shù)的框架和一些設(shè)計模式中都能看到反射的身影(MVC...
    su9257_海瀾閱讀 17,409評論 0 24
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 快要過年了,你今年過年回家嗎?你是怎么回家呢?你回家需要多長時間呢?回家的路有多遠?離開學(xué)校后就一直在路上,家更多...
    翎硯閱讀 430評論 0 0

友情鏈接更多精彩內(nèi)容