国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

你應該知道的c# 反射詳解

2019-11-17 03:05:15
字體:
來源:轉載
供稿:網友
你應該知道的c# 反射詳解

C#反射

首先了解C#反射的概念,反射是一個運行庫類型發現的過程。通過反射可以得到一個給定程序集所包含的所有類型的列表, 這個列表包括給定類型中定義的方法、字段、屬性和事件。也可以動態的發現一組給定類支持的借口、方法的參數和其他 相關信息如基類、命名空間、數據清單等。

C#反射命名空間詳細介紹:

1.System.Reflection命名空間內的各類型

(1) Assembly通過它可以加載、了解和操縱一個程序集

(2) AssemblyName 通過它可以找到大量隱藏在程序集的身份中的信息,如版本信息、區域信息等

(3) EventInfo 事件的信息

(4) FieldInfo 字段的信息

(5) MethodInfo 方法的信息

(6) ParameterInfo 參數的信息

(7) PRopertyInfo 屬性的信息

(8) MemberInfo 是抽象基類,為 EventInfo、FieldInfo 、MethodInfo、PropertyInfo等類型定義了公共的行為。

(9) Module 用來訪問帶有多文件程序集的給定模塊

2.System.Type類

System.Type支持的成員可以分為這樣幾類

(1) Is*** 用來檢查一個類型的元數據,如IsAbstract、IsClass、IsValueType等等

(2) Get*** 用來從類型得到指定項目,如GetEvent()得到類型的一個指定的事件(EventInfo)。 另外,這些方法都有一個單數版本和一個復數版本。如GetEvent()對應有一個復數版本GetEvents(), 該方法返回一個相關的EventInfo數組。

(3) FindMembers() 根據查詢條件返回一個MemberInfo類型的數組

(4)GetType() 該靜態方法根據一個字符串名稱返回一個Type實例

(5)InvokeMember() 對給定項目進行晚期綁定

3.得到一個Type類型實例的三種方法

因為Type是一個抽象類,所以不能直接使用new關鍵字創建一個Type對象

(1)使用System.Object.GetType()

Person pe=new Person(); //---------定義pe為person類的一個對象 Type t=pe.GetType();

(2)使用System.Type.GetType()靜態方法,參數為類型的完全限定名

Type t=Type.GetType("Entity.Person"); 該方法被重載,允許指定兩個布爾類型的參數,一個用來控制當前類型不能找到時是否拋出異常,

另一個用來指示是否區分字符串大小寫

Type t=Type.GetType("Entity.Person",false,true); 注意到傳入的字符串并沒有包含類型所在的程序集信息,此時該類型便被認為是定義在當前執行的程序集中的。

要得到一個外部私有程序集的類型元數據時,字符串參數必須使用類型完全限定名加上類型所在程序集的友好名字

Type t=Type.GetType("Entity.Person","Entity"); //------"Entity"即為類型所在程序集的友好名字 嵌套類型:傳入的字符串可以指定一個+標記來表示一個嵌套類型,

如希望得到一個嵌套在person類中的枚舉類型City的類型信息,則可以這樣

Type t=Type.GetType("Entity.person+City");

(3)使用typeof運算符

Type t=typeof(person); 三種方法的比較:

使用第一種方法必須先建立一個實例,而后兩種方法不必先建立實例。但使用typeof運算符仍然需要知道類型的編譯時信息,

而使用System.Type.GetType()靜態方法不需要知道類型的編譯時信息,所以是首選方法。

一個最簡單的C#反射實例,首先編寫類庫如下: namespace ReflectionTest { public class WriteTest { //帶參數的公共方法 public void WriteString(string s, int i) { Console.WriteLine("WriteString:" + s + i.ToString()); } //帶一個參數的靜態方法 public static void StaticWriteString(string s) { Console.WriteLine("StaticWriteString:" + s); } //不帶參數的靜態方法 public static void NoneParaWriteString() { Console.WriteLine("NoParaWriteString"); } } }

classTestApp { public static void Main() { Assembly ass; Type type; Object obj; //用來測試靜態方法 Object any = new Object(); //指定類庫文件必須使用絕對路徑,不能使用相對路徑 ass = Assembly.LoadFile(@"D:/Source Code/00.C#Sudy/01.Reflection/01/ReflectTest.dll"); //命名空間和類的名字必須一起指定 type = ass.GetType("ReflectionTest.WriteTest"); /**//*example1---------*/ MethodInfo method = type.GetMethod("WriteString"); string test = "test"; int i = 1; Object[] parametors = new Object[]{test,i}; //在例子1種必須實例化反射要反射的類,因為要使用的方法并不是靜態方法。 //創建對象實例 obj = ass.CreateInstance("ReflectionTest.WriteTest"); //執行帶參數的公共方法 method.Invoke(obj, parametors); //method.Invoke(any, parametors);//異常:必須實例化反射要反射的類,因為要使用的方法并不是靜態方法。 /**//*example2----------*/ method = type.GetMethod("StaticWriteString"); method.Invoke(null, new string[] { "test"}); //第一個參數忽略 //對于第一個參數是無視的,也就是我們寫什么都不會被調用, //即使我們隨便new了一個any這樣的Object,當然這種寫法是不推薦的。 //但是對應在例子1種我們如果Invoke的時候用了類型不一致的實例來做為參數的話,將會導致一個運行時的錯誤。 method.Invoke(obj, new string[] { "test"}); method.Invoke(any, new string[] { "test"}); /**//*example3-----------*/ method = type.GetMethod("NoneParaWriteString"); //調用無參數靜態方法的例子,這時候兩個參數我們都不需要指定,用null就可以了。s method.Invoke(null, null); } }

從上面的總結中可以看出,對于外部調用的動態庫應用反射時要用到Assembly.LoadFile(),然后才是獲取類型、執行方法等; 當用反射創建當前程序集中對象實例或執行某個類下靜態方法時只需通過Type.GetType("類的完整名")。

整理2

在還不太熟悉反射的昨天,以為反射很神秘,在網上到處找答案.今天找了段代碼敲了一下,茅塞頓開!其實反射也就那么簡單的一回事! 反射是一種機制,通過這種機制我們可以知道一個未知類型的類型信息.比如,有一個對象a,這個對象不是我們定義的,也許是通過網絡捕捉到的,也許是使用泛型定義的,但我們想知道這個對象的類型信息,想知道這個對象有哪些方法或者屬性什么的.甚至我們想進一步調用這個對象的方法.關鍵是現在我們只知道它是一個對象,不知道它的類型,自然不會知道它有哪些方法等信息.這時我們該怎么辦?反射機制就是解決這么一個問題的.通過反射機制我們可以知道未知類型對象的類型信息.   再比如,我們有一個dll文件,我們想調用里面的類.現在假設這個dll文件的類的定義,數量等不是固定的,是經常變化的.也許某一天你要在這個dll里面增加一個類定義.也許你覺得這沒什么問題,現在關鍵是我們在另一個程序集里面要調用這個dll,這是我們的程序必須能夠適應這個dll的變化,也就是說即使改變了dll文件的定義也不需要改變我們的程序集.這時候我們就會使用一個未知dll.我們該怎么辦?同樣,反射機制幫助了我們,我們可以通過反射來實現.   說白了,反射就是能知道我們未知類型的類型信息這么一個東西.沒什么神秘可講!

  今天我先講一個獲得程序集信息的例子.   下面我們來舉一個例子.例子的思路是這樣的:我們有一個dll.該dll里面有許多關于運動的類.每一個類記錄了一種體育運動的信息.我們在另外一個程序里面要知道這個dll的信息:(如果你還不能明白我的意思,請耐心的照我的步驟把這個過程走一變!)   第一步:我們建一個文件Sport.cs.內容如下:   using System;   public abstract class Sport   {    protected string name;   public abstract string GetDuration();   public abstract string GetName();   }   咱們用命令"csc /t:library Sport.cs"編譯它.   第二步,我們再建一個名為SomeSports.cs的文件,內容如下:

C#代碼Flashvars" value="clipboard=using%20System%3B%0Apublic%20class%20Football%3asport%0A%7B%0A%20%20%20public%20Football()%0A%20%20%20%7B%0A%20%20%20%20%20%20name%20%3D%20%22Football%22%3B%0A%20%20%20%7D%0A%20%20%20public%20override%20string%20GetDuration()%0A%20%20%20%7B%0A%20%20%20%20%20%20return%20%22four%2015%20minute%20quarters%22%3B%0A%20%20%20%7D%0A%20%20%20%20%0A%20%20%20public%20override%20string%20GetName()%0A%20%20%20%7B%0A%20%20%20%20%20%20return%20name%3B%0A%20%20%20%7D%0A%7D%0A%0A%0Apublic%20class%20Hockey%3ASport%0A%7B%0A%20%20%20public%20Hockey()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20name%20%3D%20%22Hockey%22%3B%0A%20%20%20%7D%0A%20%20%20public%20override%20string%20GetDuration()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20return%20%22three%2020%20minute%20periods%22%3B%0A%20%20%20%7D%0A%20%20%20public%20override%20string%20GetName()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20return%20name%3B%0A%20%20%20%7D%0A%7D%0A%0Apublic%20class%20Soccer%3ASport%0A%7B%0A%20%20%20public%20Soccer()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20name%20%3D%20%22Soccer%22%3B%0A%20%20%20%7D%0A%20%20%20public%20override%20string%20GetDuration()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20return%20%22two%2045%20minute%20halves%22%3B%0A%20%20%20%7D%0A%20%20%20public%20override%20string%20GetName()%0A%20%20%20%7B%0A%20%20%20%20%20%20%20return%20name%3B%0A%20%20%20%7D%0A%7D%0A%0A%E3%80%80%E3%80%80%E4%B8%8B%E9%9D%A2%E6%88%91%E4%BB%AC%E7%94%A8%E5%91%BD%E4%BB%A4%EF%BC%82csc%20%2Ft%3Alibrary%20%2Fr%3ASport.dll%20SomeSports.cs%EF%BC%82%E7%BC%96%E8%AF%91%E8%AF%A5%E6%96%87%E4%BB%B6%EF%BC%8E%0A%E3%80%80%E3%80%80%E7%8E%B0%E5%9C%A8%E6%88%91%E4%BB%AC%E6%9C%89%E4%BA%86%E6%88%91%E4%BB%AC%E7%9A%84%E8%BF%90%E5%8A%A8%E4%BF%A1%E6%81%AFdll%E6%96%87%E4%BB%B6%EF%BC%8E%E7%8E%B0%E5%9C%A8%E6%88%91%E4%BB%AC%E6%83%B3%E9%80%9A%E8%BF%87%E7%A8%8B%E5%BA%8F%E7%9F%A5%E9%81%93%E9%87%8C%E9%9D%A2%E6%9C%89%E5%93%AA%E4%BA%9B%E7%B1%BB%EF%BC%8E%E8%AF%B7%E8%BF%9B%E5%85%A5%E6%9C%80%E5%90%8E%E4%B8%80%E6%AD%A5%EF%BC%9A%0A%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E6%88%91%E4%BB%AC%E5%88%9B%E5%BB%BA%E6%96%87%E4%BB%B6AssemblyDemo%EF%BC%8Ecs%EF%BC%82.%E5%86%85%E5%AE%B9%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%0A%0A%0Ausing%20System%3B%0Ausing%20System.Reflection%3B%0A%0Apublic%20class%20AssemblyDemo%0A%7B%0A%20%20%20%20%20public%20static%20void%20Main(string%5B%5D%20args)%0A%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20int%20i%2Cj%3B%0A%20%20%20%20%20%20%20%20%20%20%2F%2F%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%20%20%20%20%20%20%20%20%20%20%2F%2FFirst%20the%20command%20line%20arguments%20are%20evaluated.if%20there%20isn't%0A%20%20%20%20%20%20%20%20%20%20%2F%2Fat%20least%20one%2Ca%20usage%20message%20is%20printed%0A%20%20%20%20%20%20%20%20%20%20%2F%2F%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%20%20%20%20%20%20%20%20%20%20if(args.GetLength(0)%3C1)%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20Console.WriteLine(%22usage%20is%20AssemblyDemo%3Clibrary_name%3E%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20else%0A%20%20%2
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高要市| 图木舒克市| 周宁县| 汨罗市| 勃利县| 阆中市| 马关县| 拜城县| 海淀区| 廊坊市| 瑞丽市| 稷山县| 天津市| 鸡泽县| 都兰县| 北票市| 翼城县| 黔西县| 连平县| 怀安县| 江口县| 合山市| 彝良县| 伊春市| 绵竹市| 颍上县| 阳东县| 榆中县| 彭阳县| 印江| 静海县| 榕江县| 安陆市| 沅陵县| 会昌县| 宁城县| 星子县| 习水县| 巴塘县| 云阳县| 洪湖市|