你應該知道的c 反射詳解

2021-09-06 16:29:15 字數 3754 閱讀 8438

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等等

(3) findmembers()   根據查詢條件返回乙個memberinfo型別的陣列

(4)gettype() 該靜態方法根據乙個字串名稱返回乙個type例項

(5)invokemember() 對給定專案進行晚期繫結

3.得到乙個type型別例項的三種方法

因為type是乙個抽象類,所以不能直接使用new關鍵字建立乙個type物件

(1)使用system.object.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()靜態方法不需要知道型別的編譯時資訊,所以是首選方法。

class

從上面的總結中可以看出,對於外部呼叫的動態庫應用反射時要用到assembly.loadfile(),然後才是獲取型別、執行方法等; 當用反射建立當前程式集中物件例項或執行某個類下靜態方法時只需通過type.gettype("類的完整名")。

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

今天我先講乙個獲得程式集資訊的例子.   下面我們來舉乙個例子.例子的思路是這樣的:我們有乙個dll.該dll裡面有許多關於運動的類.每乙個類記錄了一種體育運動的資訊.我們在另外乙個程式裡面要知道這個dll的資訊:(如果你還不能明白我的意思,請耐心的照我的步驟把這個過程走一變!)   第一步:我們建乙個檔案sport.cs.內容如下:   using system;   public abstract class sport      咱們用命令"csc /t:library sport.cs"編譯它.   第二步,我們再建乙個名為somesports.cs的檔案,內容如下:

c#**

using system;  

public class football:sport  

public override string getduration()  

public override string getname()  

}  public class hockey:sport  

public override string getduration()  

public override string getname()  

}  public class soccer:sport  

public override string getduration()  

public override string getname()  

}  下面我們用命令"csc /t:library /r:sport.dll somesports.cs"編譯該檔案.  

現在我們有了我們的運動資訊dll檔案.現在我們想通過程式知道裡面有哪些類.請進入最後一步:  

第三步:我們建立檔案assemblydemo.cs".內容如下:  

using system;  

using system.reflection;  

public class assemblydemo  

else  

i=types.length - 1;  

console.write("make selection(0-"+i+");");  

j=convert.toint32(console.readline());  

console.writeline();  

if(types[j].issubclassof(typeof(sport)))  

else  

}  }  }  

}  

咱們用命令"csc /r:sport.dll assemblydemo.cs"編譯該檔案. 下面我們用"assemblydemo somesports.dll"執行該程式.

你應該知道的C 檔案操作

資料型別 描述ofstream該資料型別表示輸出檔案流,用於建立檔案並且向檔案中寫入資訊 ifstream該資料型別表示輸入檔案流,用於從檔案中讀取資訊 fstream改資料型別通常表示檔案流,且同時具有ofstreamifstream倆種功能 在c 中,fstream可以建立檔案,向檔案內寫入資訊...

你應該知道git rebase

多人開發時,一般都會使用git來進行 管理。使用過git的童鞋肯定對git pullgit pushgit merge非常熟悉。那麼,大家有沒有了解過git rebase命令呢?rebase翻譯成中文叫 變基 相比merge,rebase並沒有進行合併操作,該命令只是提取了當前分支的修改,將其複製在...

你應該知道的 RPC 原理

在校期間大家都寫過不少程式,比如寫個hello world服務類,然後本地呼叫下,如下所示。這些程式的特點是服務消費方和服務提供方是本地呼叫關係。而一旦踏入公司尤其是大型網際網路公司就會發現,公司的系統都由成千上萬大大小小的服務組成,各服務部署在不同的機器上,由不同的團隊負責。這時就會遇到兩個問題 ...