搜尋
首頁後端開發C#.Net教程C#學習之Reflection
C#學習之ReflectionDec 20, 2016 pm 05:18 PM
c

1、什麼是反射: 
Reflection,中文翻譯為反射。
這是.Net中獲取運行時類型資訊的方式 ,.Net的應用程式由幾個部分: '組件(Assembly)'、'模組(Module)'、'類型(class)'組成,而反射提供一種編程的方式,讓程式設計師可以在程式運行期獲得這幾個組成部分的相關資訊。

反射的概述 

反射的定義:審查元資料並收集關於它的類型資訊的能力 。元資料(編譯以後最基本的資料單 元)就是一大堆的表,當編譯組件或模組時,編譯器會建立一個類別定義表,一個欄位定義表,和一個方法定義表等。 System.reflection命名 空間包含的幾個類,讓你可以反射(解析)這些元資料表的程式碼。


2、反射的具體用途:

(1)使用Assembly定義和載入程式集,載入在程式集清單中列出模組,以及從此程式集中尋找類型並建立該類型的實例。 
(2)使用 Module了解包含模組的組件以及模組中的類別等,還可以取得在模組上定義的所有全域方法或其他特定的非全域方法。 
(3)使用 ConstructorInfo來了解建構子的名稱、參數、存取修飾符(如pulic 或private)和實作詳細資訊(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法來呼叫特定的建構子。 
(4)使用MethodInfo來了解方法的名稱、回傳類型、參數、存取修飾符(如 pulic 或private)和實作詳細資訊(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法來呼叫特定的 方法。 
(5)使用FiedInfo了解欄位的名稱、存取修飾符(如public或private)和實作詳細資訊(如static)等,並取得 或設定欄位值。 
(6)使用EventInfo了解事件的名稱、事件處理程序資料類型、自訂屬性、宣告類型和反射類型等,新增或移除事件處理程 序。 
(7)使用PropertyInfo了解屬性的名稱、資料型態、宣告型別、反射型別及唯讀或可寫入狀態等,取得或設定屬性值。 
(8)使用ParameterInfo來了解參數的名稱、資料型別、是輸入參數或輸出參數,以及參數在方法簽章中的位置等。


3、與反射相關的命名空間:


System.Reflection.Assembly

System.Reflection.MemberInfo
System.Reflection.Re.InfoSystem.Reflection.MemberInfo
System.Reflection.Re.id.S. ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type


4、反射的層次模型:

: 1. 可以使用反射動態地建立類型的實例,將類型綁定到現有對象,或從現有對像中取得類型
2. 應用程式需要在執行時間從某個特定的程式集中載入一個特定的類型,以便在實現某個任務時可以用到反射。
3. 反射主要應用與類別庫,這些類別庫需要知道一個類型的定義,以便提供更多的功能。

應用要點:

1. 現實應用程式中很少有應用程式需要使用反射類型
2. 使用反射動態綁定需要犧牲效能
3. 有些元資料資訊是不能透過反射取得的
4. 某些反射類型是專門為那些CLR開發編譯器的開發使用的,所以你要意識到不是所有的反射類型都是適合每個人的。

6、反射的實際應用:

反射appDomain 的程序集 

static void Main
{
// 透過GetAssemblies 呼叫appDomain的所有程序集
foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies(Assembly assem in Appdomain.currentDomain.GetAssemblies(GetAssembly)> reflector.ReflectOnAssembly(assem)
}
}

說明:呼叫AppDomain 物件的GetAssemblies 方法將傳回由System.Reflection.Assembly元素組成的陣列。

反射單一組件 

我們可以顯示的呼叫其中的一個組件,system.reflecton.assembly 類型提供了以下三種方法:

1. Load 方法:極力推薦的一種方法,Load 方法帶有一個組件標誌並載入它,Load 將引起CLR把策略應用到組件上,先後在全域組件緩衝區,應用程式基目錄和私有路徑下面查找該程序集,如果找不到該程序集系統拋出異常。
2. LoadFrom 方法:傳遞一個組件檔案的路徑名(包括副檔名),CLR會載入您指定的這個程式集,傳遞的這個參數不能包含任何關於版本號的信息,區域性,和公鑰訊息, 如果在指定路徑找不到組件拋出例外。
3. LoadWithPartialName:永遠不要使用這個方法,因為應用程式無法確定再在載入的組件的版本。此方法的唯一用途是幫助那些在.Net框 架的測試環節使用.net 框架提供的某種行為的客戶,這個方法將最終被拋棄不用。
注意:system.AppDomain 也提供了一種Load 方法,他和Assembly的靜態Load 方法不一樣,AppDomain的load 方法是一種實例方法,返回的是一個對程序集的引用,Assembly的靜態Load 方發將程式集按值封裝發回給發出呼叫的AppDomain.盡量避免使用AppDomain的load 方法

利用反射獲取類型資訊 

一個簡單的利用反射獲取類型資訊的例子:

using system;
using sytem. reflection;
class reflecting
{
static void Main(string[]args)
{
reflecting reflect=new reflecting();// 定義一個新的自身類別
//呼叫一個reflecting.exe大約assembly.loadfrom(“reflecting.exe”)
reflect.getreflectioninfo(myAssembly);// 取得反射資訊
}
// 定義一個取得反射內容的方法
void getreflectioninfo(assembly mhyasse)> myassemby.Gettypes();//取得類型
foreach (type type in typearr)//針對每個類型取得詳細資訊
{
//取得類型的結構資訊
constructorinfo[] myconstructors=type.GetConstructors;
//取得類型的欄位資訊
fieldinfo[] myfields=type.GetFiedls()
//取得方法資訊
MethodInfo myMethodInfo=type.GetMethods();
// 取得屬性資訊
propertyInfo[] myproperties=type.Gpperties=type.取得事件資訊
EventInfo[] Myevents=type.GetEvents;
}
}
}

其它幾種取得type物件的方法:

1. System.type 參數為字串類型,該字串必須指定類型的完整名稱(包括其命名空間)
2. System.type 提供了兩個實例方法:GetNestedType,GetNestedTypes
3. Syetem.Reflection.Assembly 類型提供的實例方法為:GetType,GetTypes,GetExporedTypes
4. System.Reflection.Moudle 提供了這些實例方法:GetType,GetTypes,FindTypes

設定反射類型的成員 

反射類型的成員就是反射層次模型中最下面的一層資料。我們可以透過type物件的 GetMembers 方法來取得一個類型的成員。如果我們使用的是不含參數的GetMembers,它只會傳回該類型的公共定義的靜態變數和實例成員,我們也可以透過使用帶有參數的 GetMembers透過參數設定來傳回指定的類型成員。特定參數參考msdn 中system.reflection.bindingflags 枚舉類型的詳細說明。

例如:

// 設定需要傳回的類型的成員內容
bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
foreach (MInfoInfomimi int temberm; mi.membertype) //輸出指定的類型成員
}

透過反射建立類型的實例 

透過反射可以取得組件的類型,我們就可以根據所獲得的組件類型來建立該類型新的實例,這也是前面提到的在運行時創建物件實現晚綁定的功能。我們可以透過下面的幾個方法來實現:

1. System.Activator 的CreateInstance方法。該方法傳回新物件的引用。
2. System.Activator 的createInstanceFrom 與上一個方法類似,不過需要指定類型及其組件。
3. System.Appdomain 的方法:createInstance,CreateInstanceAndUnwrap,CreateInstranceFrom和 CreateInstraceFromAndUnwrap
4. System.type 的InvokeMember實例方法:這個方法傳回一個與傳入參數相符的建構函數,並且建構這個型別。
5. System.reflection.constructinfo 的Invoke實例方法

反射類型的介面 

如果你想要取得一個類型繼承的所有介面集合,可以呼叫 Type的FindInterfaces GetInterface或 GetInterfaces。所有這些方法只能返回該類型直接繼承的接口,他們不會返回從一個接口繼承下來的接口。要返回介面的基礎介面必須再次呼叫上述方法。

反射的性能 

反射時CLR要做更多的工作:校驗參數,檢查權限等等,速度是非常慢的。 盡量不要使用反射進行編程,對於打算編寫一個動態構造類型(晚綁定)的應用程序,可採取以下幾種方式進行代替:

1.透過類別的繼承關係。讓該類型從一個編譯時可知的基礎類型派生出來,在運行時產生該類型的一個實例,將對其的引用放到其基礎類型的一個變數中,然後調用該基礎類型的虛擬方法。
2.透過接口實現。在運行時,建構該類型的一個實例,將對其的引用放到其介面類型的變數中,然後呼叫該介面定義的虛擬方法。
3.透過委託實現。讓該類型實作一個方法,其名稱和原型都與一個在編譯時就已知的委託相符。在執行時先建構該類型的實例,然後在用該方法的物件及名稱建構出該委託的實例,接著透過委託呼叫你想要的方法。這個方法相對與前面兩個方法所做的工作要多一些,效率也更低一些。

使用注意事項:

1、跨程序集的反射

在開發中,經常會遇到這種情況,在A.dll中需要反射B.dll中的類型,如果稍不注意,就會產生運行時錯誤。關於跨程式集的反射,記住兩點:
(1)如果使用typeof,編譯能通過,則跨程式集的反射一定可以正常運作。可以說,typeof是支援強型別的。例如

Type supType = typeof(EnterpriseServerBase.DataAccess.IDBAccesser) ;

如果目前組件沒有新增對EnterpriseServerBase.dll的引用,則編譯會報錯。

(2)如果使用Type.GetType,情況就複雜些,這是因為Type.GetType是非強類型的。 Type.GetType的參數是一個 string,當string表示的目標類型不在目前程式集中,則執行時Type.GetType會傳回null。解決的方法是:先載入目標組件,然後再使用Assembly.GetType方法。如

Assembly asmb = Assembly.LoadFrom("EnterpriseServerBase.dll") ;
Type supType = asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") ;

注意,使用類型. EnterpriseServerBase.dll的引用,Type.GetType("EnterpriseServerBase.DataAccess.IDBAccesser")也會傳回null,這是因為Type.GetType只會在目前程式集中進行型別搜尋。

2、反射時判斷一個方法的回傳型別是否為void

Type serviceType = typeof(T);
MethodInfo methodInfo = serviceType.GetMethod(methodName);
即可。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
C语言中的常量是什么,可以举一个例子吗?C语言中的常量是什么,可以举一个例子吗?Aug 28, 2023 pm 10:45 PM

常量也称为变量,一旦定义,其值在程序执行期间就不会改变。因此,我们可以将变量声明为引用固定值的常量。它也被称为文字。必须使用Const关键字来定义常量。语法C编程语言中使用的常量语法如下-consttypeVariableName;(or)consttype*VariableName;不同类型的常量在C编程语言中使用的不同类型的常量如下所示:整数常量-例如:1,0,34,4567浮点数常量-例如:0.0,156.89,23.456八进制和十六进制常量-例如:十六进制:0x2a,0xaa..八进制

VSCode和VS C++IntelliSense无法工作或拾取库VSCode和VS C++IntelliSense无法工作或拾取库Feb 29, 2024 pm 01:28 PM

VS代码和VisualStudioC++IntelliSense可能无法拾取库,尤其是在处理大型项目时。当我们将鼠标悬停在#Include<;wx/wx.h>;上时,我们看到了错误消息“CannotOpen源文件‘string.h’”(依赖于“wx/wx.h”),有时,自动完成功能无法响应。在这篇文章中,我们将看到如果VSCode和VSC++IntelliSense不能工作或不能提取库,你可以做些什么。为什么我的智能感知不能在C++中工作?处理大文件时,IntelliSense有时

修复Xbox错误代码8C230002修复Xbox错误代码8C230002Feb 27, 2024 pm 03:55 PM

您是否由于错误代码8C230002而无法在Xbox上购买或观看内容?一些用户在尝试购买或在其控制台上观看内容时不断收到此错误。抱歉,Xbox服务出现问题。稍后再试.有关此问题的帮助,请访问www.xbox.com/errorhelp。状态代码:8C230002这种错误代码通常是由于暂时的服务器或网络问题引起的。但是,还有可能是由于帐户的隐私设置或家长控制等其他原因,这些可能会阻止您购买或观看特定内容。修复Xbox错误代码8C230002如果您尝试在Xbox控制台上观看或购买内容时收到错误代码8C

递归程序在C++中找到数组的最小和最大元素递归程序在C++中找到数组的最小和最大元素Aug 31, 2023 pm 07:37 PM

我们以整数数组Arr[]作为输入。目标是使用递归方法在数组中找到最大和最小的元素。由于我们使用递归,我们将遍历整个数组,直到达到长度=1,然后返回A[0],这形成了基本情况。否则,将当前元素与当前最小或最大值进行比较,并通过递归更新其值以供后续元素使用。让我们看看这个的各种输入输出场景&minus;输入&nbsp;&minus;Arr={12,67,99,76,32};输出&nbsp;&minus;数组中的最大值:99解释&nbsp;&mi

中国东方航空宣布C919客机即将投入实际运营中国东方航空宣布C919客机即将投入实际运营May 28, 2023 pm 11:43 PM

5月25日消息,中国东方航空在业绩说明会上披露了关于C919客机的最新进展。据公司表示,与中国商飞签署的C919采购协议已于2021年3月正式生效,其中首架C919飞机已在2022年底交付。预计不久之后,该飞机将正式投入实际运营。东方航空将以上海为主要基地进行C919的商业运营,并计划在2022年和2023年引进总共5架C919客机。公司表示,未来的引进计划将根据实际运营情况和航线网络规划来确定。据小编了解,C919是中国具有完全自主知识产权的全球新一代单通道干线客机,符合国际通行的适航标准。该

C++程序打印数字的螺旋图案C++程序打印数字的螺旋图案Sep 05, 2023 pm 06:25 PM

以不同格式显示数字是学习基本编码问题之一。不同的编码概念,如条件语句和循环语句。有不同的程序中,我们使用特殊字符(如星号)来打印三角形或正方形。在本文中,我们将以螺旋形式打印数字,就像C++中的正方形一样。我们将行数n作为输入,然后从左上角开始移向右侧,然后向下,然后向左,然后向上,然后再次向右,以此类推等等。螺旋图案与数字123456724252627282982340414243309223948494431102138474645321120373635343312191817161514

C语言中的void关键字的作用C语言中的void关键字的作用Feb 19, 2024 pm 11:33 PM

C中的void是一个特殊的关键字,用来表示空类型,也就是指没有具体类型的数据。在C语言中,void通常用于以下三个方面。函数返回类型为void在C语言中,函数可以有不同的返回类型,例如int、float、char等。然而,如果函数不返回任何值,则可以将返回类型设为void。这意味着函数执行完毕后,并不返回具体的数值。例如:voidhelloWorld()

23 年来首次,C# 获得了 TIOBE 2023 年度编程语言奖23 年来首次,C# 获得了 TIOBE 2023 年度编程语言奖Jan 11, 2024 pm 04:45 PM

根据TIOBE编程社区指数,该指数是衡量编程语言受欢迎程度的标准之一,通过收集来自全球工程师、课程、供应商和搜索引擎的数据进行评估。2024年1月TIOBE指数于近日发布,同时官方公布了2023年编程语言排名,C#荣获TIOBE2023年度编程语言,这是23年来C#首次拿下这一荣誉。TIOBE官方新闻稿称,C#已经稳居前10名长达20多年,如今它正在追赶四大语言,成为一年内涨幅最大的编程语言(+1.43%),当之无愧地获得了该奖项。排名第二的是Scratch(+0.83%)和Fortran(+0

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具