C 語言系列講座(16) 動態型別查詢

2021-03-31 08:56:28 字數 2761 閱讀 2263

動態型別查詢

我們知道,c#編譯後的pe檔案主要由il**和元資料組成,元資料為.***元件提供了豐富的自描述特性,它使得我們可以在**執行時獲知元件中的型別等重要的資訊。在c#中這是通過一種稱做對映(reflection)的機制來完成的。先看乙個示例,在此首先建立乙個簡單的型別:

// ******type.cs

public class myclass

set

} public void print()

} 用編譯命令csc /t:library ******type.cs編譯上面的檔案得到******type.dll。接下來實現查詢型別的測試程式:

//test.cs

using system;

using system.reflection;

class test」,t.name);

//獲取型別的名字

fieldinfo fiarr=t.getfields();

//獲取所有的公有域

console.write(「the

fields :」,fiarr.length);

foreach(fieldinfo o in

fiarr)

console.writeline();

propertyinfo piarr=t.getproperties();

//獲取所有的公有屬性

console.write(「the properties :」,piarr.length);

foreach(propertyinfo o in piarr)

console.writeline();

methodinfo miarr=t.getmethods();//獲取所有的公有方法

console.write(「the methods :」,miarr.length);

foreach(methodinfo o in miarr)

} }

用編譯命令csc /r:******type.dll test.cs編譯後執行,可得到下面的輸出:

the type name : myclass

the 0 fields :

the 1 properties :count

the 7 methods :gethashcode equals tostring get_count set_count print gettype

在上面的例子中,首先通過 typeof(myclass)獲得myclass類的型別資訊,當然也可以通過建立物件例項,然後呼叫物件例項的gettype方法來獲得(每個類都從object根類中繼承獲得此方法)。在擁有了型別資訊(變數t)後,便可以獲得其型別的名字、該型別含有的公有域、公有屬性、公有方法。注意: 這裡c#的對映機制只允許獲取型別的公有資訊,這符合物件導向的封裝原則。這也是為什麼雖然實現了count域,查詢型別得到的輸出卻是「the 0 fields:」——如果將******type.cs中的count域改為public公有,將會得到它的查詢資訊。其中4個方法(gethashcode、equals、tostring、gettype)都是繼承自object類的公有方法,而方法get_count 和set_count則是實現count屬性的「副產物」——這符合前面講述的屬性本質上為方法的變體。實際上,system.type類各種各樣的成員使得我們能夠獲得幾乎所有與型別相關的公有資訊。在system.reflection命名空間下的各個類都可以獲得各個程式設計元素較詳細的資訊,如方法的引數與返回值、域的型別、列舉的各個值等。

動態建立與呼叫

實際上對映遠不止動態地獲知元件的型別資訊,它還能在獲得型別資訊的基礎上,在**執行時進行型別的動態建立與方法的動態呼叫,甚至動態地建立並執行il**!

動態呼叫為c#的元件提供了遲繫結功能,它使元件之間在執行時整合變得極為方便!利用前面建立的簡單元件******type.dll,來看一看怎樣完成物件的動態建立和方法的動態呼叫:

// dynamicexe.cs

using system;

using system.reflection;

class test , return :」,mi.name,re);

} }

} }

} }

用編譯命令csc /r:******type.dll dynamicexe.cs編譯後執行,可得到下面的輸出:

gethashcode, return :8

tostring, return :myclass

get_count, return :100

100

print, return :

gettype, return :myclass

我們在上面的例子中給出了被動態呼叫的方法名字和返回值。其中輸出的第四行為100,它是動態呼叫方法myclass.print() 的輸出。需要指出的是呼叫的是型別的公有無引數例項方法。給出元件的名字,應用assembly.loadfrom,我們便可以動態地裝載元件。activator.createinstance允許動態地建立型別(這裡只通過無引數的構造器來建立),實際上用它建立出來的型別和用「myclass o=new myclass()」建立出來的型別一樣。進而,還可以在查詢到的成員的基礎上,對它們進行動態呼叫。

microsoft.***從底層的元資料設計入手,為對映機制提供了非常堅實的基礎。命名空間system.reflection和system.reflection.emit為操作這種對映提供了實實在在的強大的api程式設計介面,大大改善了元件的設計環境,提高了元件的互動能力!

MySQL查詢優化技術系列講座之使用索引(一)

索引是提高查詢速度的最重要的工具。當然還有其它的一些技術可供使用,但是一般來說引起最大效能差異的都是索引的正確使用。在mysql郵件列表中,人們 經常詢問那些讓查詢執行得更快的方法。在大多數情況下,我們應該懷疑資料表上有沒有索引,並且通常在新增索引之後立即解決了問題。當然,並不總是這樣簡單 就可以解...

C 執行緒系列講座 4 同步與死鎖

雖然執行緒可以在一定程度上提高程式執行的效率,但也會產生一些 讓我們先看看如下的 class increment public intresult set public void inc class program for inti 0 i threads.length i console.writ...

C 執行緒系列講座 4 同步與死鎖

雖然執行緒可以在一定程度上提高程式執行的效率,但也會產生一些 讓我們先看看如下的 class increment public intresult set public void inc class program for inti 0 i threads.length i console.writ...