C 語法:反射架構(gòu)師的入門_第1頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、c 語法:反射,架構(gòu)師的入門前言編程其實(shí)就是寫代碼,而寫代碼目的就是實(shí)現(xiàn)業(yè)務(wù),所以,語法和框架也是為了實(shí)現(xiàn)業(yè)務(wù)而存在的。因此,不管多么巍峨上的目標(biāo),實(shí)質(zhì)上都是業(yè)務(wù)。所以,我認(rèn)為不要把寫代碼升高到科學(xué)的高度。升高到藝術(shù)就可以了,由于藝術(shù)本身也沒有高度。軟件設(shè)計(jì)存在過度設(shè)計(jì),語法和框架的理解,也存在過度理解。比如,反編譯下,看看反射是怎么實(shí)現(xiàn)的。有愛好是好事,但就算知道了反射的本質(zhì),了解了反射是如何設(shè)計(jì)的,你技術(shù)也沒什么質(zhì)的轉(zhuǎn)變。由于,技術(shù)水平終于還是要落實(shí)到應(yīng)用上。在比如,過度的追求代碼性能,也不見得是一件好事,由于,大多數(shù)狀況下,硬件比程序員廉價(jià)多了。(注重這里指的是代碼不是算法和數(shù)據(jù)庫性能)

2、所以,不論什么事,過度了,總不是好事。本篇文章主要介紹c反射【使用】。反射是架構(gòu)師必會(huì)的基礎(chǔ),由于任何一個(gè)被設(shè)計(jì)出來的框架,都要用法反射。反射也是最隱蔽的語法,由于反射寫出來后,通常它會(huì)被挺直封裝,然后調(diào)用者就只負(fù)責(zé)用法,不再關(guān)注他的詳細(xì)實(shí)現(xiàn)。這與它的特性有關(guān),由于反射就是為了削減代碼冗余而存在的,所以,看不見很正常。反射的定義官方定義:反射提供了封裝程序集、模塊和類型的對(duì)象(type 類型)??梢杂梅ǚ瓷鋭?dòng)態(tài)創(chuàng)建類型的實(shí)例,將類型綁定到現(xiàn)有對(duì)象,或從現(xiàn)有對(duì)象獵取類型并調(diào)用其辦法或拜訪其字段和屬性。假如代碼中用法了屬性,可以利用反射對(duì)它們舉行拜訪??床欢??不要緊,我們把它翻譯成人類可理解的語言

3、。c編程語言中,最常用法的是類和類中的函數(shù)和屬性。正向調(diào)用的辦法是,創(chuàng)建類,然后用類創(chuàng)建一個(gè)對(duì)象。接下來就可以用這個(gè)對(duì)象調(diào)用類中的辦法和屬性了。而反射,就是相對(duì)于這種正向調(diào)用的存在。即,它是反向調(diào)用。反射可以通過類名的字符串來創(chuàng)建類,可以通過函數(shù)名的字符串和屬性名的字符串,來調(diào)用類下的函數(shù)和屬性。有學(xué)生會(huì)問了, 既然正向可以調(diào)用,那么反向調(diào)用干什么呢?會(huì)有這種問題的學(xué)生,先別焦急,繼續(xù)往下看,反射既然存在,就必定有存在的道理。反射的基礎(chǔ)應(yīng)用1、類反射先看下面代碼;代碼為通過類名稱的字符,反射出類的對(duì)象。public class reflectionsyntax public static vo

4、id excute() type type = gettype("syntax.kiba"); kiba kiba = (kiba)activator.createinstance(type); type type2 = gettype2("syntax.kiba"); kiba kiba2 = (kiba)activator.createinstance(type2); public static type gettype(string fullname) assembly assembly = assembly.loa

5、d("syntax"); type type = assembly.gettype(fullname, true, false); return type; public static type gettype2(string fullname) type t = type.gettype(fullname); return t; public class kiba public void printname() console.writeline("kiba518"); 在代碼中我們看到,反射時(shí)傳遞了字符串&qu

6、ot;syntax.kiba",然后通過解析字符串,獵取到了該字符串對(duì)應(yīng)的類的類型,最后再借助activator來輔助創(chuàng)建類的實(shí)例。其中字符串"syntax.kiba"是一個(gè)徹低限定名。什么是徹低限定名?徹低限定名就是命名空間+類名。在反射的時(shí)候,需要我們傳遞徹低限定名來確定到底要去哪個(gè)命名空間,找哪個(gè)類。在代碼中我們還可以看到,獵取類型的方式有兩種,一種是較復(fù)雜的,一種是容易的。gettype2辦法是容易的獵取類別,通過type挺直就解析了字符串。而gettype則先舉行了加載assembly(組件),然后再由組件獵取類型。兩者有什么區(qū)分

7、呢?區(qū)分是,用type挺直解析,只能解析當(dāng)前命名空間下的類。假如該類存在于引用的dll中,就解析不了。而gettype辦法中的assembly.load指定了程序集名,所以,在反射時(shí),就會(huì)去指定的命名空間里找對(duì)應(yīng)的類。這樣就能找到非本程序集下的類了。assembly.load指定了程序集名這句話不好理解?不要緊,換個(gè)表達(dá),assembly.load指定了命名空間的名稱,所以反射時(shí),會(huì)去這個(gè)命名空間里找類,這樣是不是就好理解了。assemblyassembly的存在讓反射變得特殊靈便,其中assembly.load不止可以導(dǎo)入我們引入的程序集(或命名空間)。也可以導(dǎo)入我們未引入程序集的dll。調(diào)

8、用模式如下:system.reflection.assembly o = system.reflection.assembly.load("mscorlib.dll"); assembly導(dǎo)入了程序集后,還可以不借助activator來輔助,自己就可以創(chuàng)建類。如下:assembly assembly = assembly.load("syntax");kiba kiba = (kiba)assembly.createinstance("syntax.kiba"); 有的學(xué)生可能會(huì)不安性能

9、,會(huì)覺得這樣反射,會(huì)使程序變慢。有這種主意的學(xué)生,其實(shí)你已經(jīng)是在過度理解語法了。這種地方的代碼性能其實(shí)是可以不用關(guān)懷的。那么,到底會(huì)不會(huì)變慢呢?答案是這樣的,假如你是用法徹低限定名來反射,速度就是一樣的。假如是反射時(shí),只寫了一個(gè)類名,那么速度就會(huì)變慢。由于它要遍歷全部的命名空間,去找這個(gè)類。即,只要反射時(shí)把類的命名空間寫全,那么速度就不會(huì)慢。2、函數(shù)反射函數(shù)的反射應(yīng)用主要是用法類methodinfo類反射,下面先看下基礎(chǔ)應(yīng)用。public static void excutemethod() assembly assembly = assembly.load("syntax&

10、amp;quot;); type type = assembly.gettype("syntax.kiba", true, false); methodinfo method = type.getmethod("printname"); object kiba = assembly.createinstance("syntax.kiba"); object pmts = new object "kiba518" ; method.invoke(kiba

11、, pmts);/執(zhí)行辦法 public class kiba public string name get; set; public void printname(string name) console.writeline(name); 一些學(xué)生第一眼看上去可能會(huì)有點(diǎn)不適應(yīng),由于好似無數(shù)類都是大家不常常用的。這也沒方法,由于這是一個(gè)進(jìn)階的過程,必需經(jīng)受從生疏到認(rèn)識(shí)。當(dāng)你認(rèn)識(shí)了這樣的代碼后,就代表你的技術(shù)水平又長進(jìn)了一個(gè)臺(tái)階。下面講解一些這些代碼。首先我們導(dǎo)入了命名空間,接著我們獵取了該命名空間下kiba這個(gè)類的類型;接下來我們通過這個(gè)類型來獵取指定名稱的函數(shù)。然后我們通過assembly創(chuàng)

12、建了一個(gè)kiba的實(shí)例,接著定義了一個(gè)參數(shù)的object數(shù)組,由于kiba類下的函數(shù)printname惟獨(dú)一個(gè)參數(shù),所以,我們只為這個(gè)object數(shù)組添加一個(gè)對(duì)象kiba518。最后,我們通過method.invoke來調(diào)用這個(gè)函數(shù),因?yàn)槭欠瓷?,所以調(diào)用時(shí),需要指定kiba類的實(shí)例對(duì)象和入?yún)?。這樣,函數(shù)的反射就實(shí)現(xiàn)了。3、屬性反射屬性反射是用propertyinfo類來實(shí)現(xiàn),下面看基礎(chǔ)的屬性反射。public static void excuteproperty() kiba kiba = new kiba(); kiba.name = "kiba518"

13、object name = reflectionsyntax.getpropertyvalue(kiba, "name"); console.writeline(name);public static object getpropertyvalue(object obj, string name) propertyinfo property = obj.gettype().getproperty(name); if (property != null) object drv1 = property.getvalue(obj, null); return dr

14、v1; else return null; 如代碼所示,首先我們定義了一個(gè)kiba的對(duì)象,并為name賦值,然后我們通過getpropertyvalue辦法,傳遞了kiba對(duì)象和要獵取值的屬性名稱。getpropertyvalue函數(shù)里通過用法propertyinfo完成了反射。有的學(xué)生可能會(huì)覺得,這個(gè)很雞肋,既然已經(jīng)得到對(duì)象,還反射做什么,挺直獵取就可以了呀。別焦急,我們接下來一起看反射的架構(gòu)應(yīng)用。反射的架構(gòu)應(yīng)用框架編寫的核心目的之一,是統(tǒng)一系統(tǒng)秩序。那么什么是系統(tǒng)秩序呢?首先我們看下系統(tǒng)的構(gòu)成,系統(tǒng)個(gè)通常是由子系統(tǒng),程序集,類,函數(shù)這四部分構(gòu)成。如下圖所示。 既然系統(tǒng)由子系統(tǒng),程序集,類,

15、函數(shù)這四個(gè)基礎(chǔ)元素構(gòu)成,那么系統(tǒng)秩序,自然指的就是這四個(gè)元素的秩序。而這四個(gè)元素最難形成秩序的就是函數(shù)了。很明顯,任何的項(xiàng)目都存在重復(fù)的函數(shù),或者功能相近的函數(shù)。而徹底杜絕這種狀況,明顯是不行能的。那么我們只好盡量是設(shè)計(jì)會(huì)避開重復(fù)元素的框架了。而反射,正是為此而存在的。反射的架構(gòu)應(yīng)用現(xiàn)實(shí)中的框架由于這樣那樣的緣由,會(huì)有千姿百態(tài)的設(shè)計(jì),所以拘泥于一種設(shè)計(jì)模式是愚蠢的,實(shí)戰(zhàn)中要多種設(shè)計(jì)模式一起應(yīng)用,局部設(shè)計(jì)有時(shí)候只取設(shè)計(jì)模式中一部分也可以。這樣才干實(shí)現(xiàn)項(xiàng)目的量身定制。所以,這里只介紹一種實(shí)戰(zhàn)的架構(gòu)應(yīng)用,一種用法反射的框架基礎(chǔ)結(jié)構(gòu)。下面請(qǐng)框架基礎(chǔ)代碼。public class client publ

16、ic void excutegetnamecommand() proxy proxy = new proxy(); getnamecommand cmd = new getnamecommand(); resultbase rb = proxy.excutecommand(cmd); public class proxy public resultbase excutecommand(commandbase command) var result = handlerswitcher.excute(command); return result as resultbase; public cla

17、ss handlerswitcher private const string methodname = "excute"/商定的辦法名 private const string classnamepostfix = "handler"/商定的處理command的類的名稱的后綴 /獵取命名空間的名稱 public static string getnamespace(commandbase command) type commandtype = command.gettype();/獵取徹低限定名 string comma

18、ndtypenames = commandtype.tostring().split('.'); string namespace = "" for (int i = 0; i plist = typeof(kiba).getproperties(system.reflection.bindingflags.instance | system.reflection.bindingflags.public).tolist();/只獵取public的屬性 foreach (propertyinfo pinfo in plist) var attr

19、s = pinfo.getcustomattributes(typeof(kibaattribute), false); if (null != attrs && attrs.length > 0) var des = (kibaattribute)attrs0).description; if (des = "clear") pinfo.setvalue(kiba, null); public class kiba kibaattribute("clear") public stri

20、ng clearname get; set; kibaattribute("noclear") public string noclearname get; set; public string normalname get; set; system.attributeusage(system.attributetargets.all)public class kibaattribute : system.attribute public string description get; set; public kibaattribute(string description) this.description = description; 如上述代碼所示, 我們通過反射,將擁有kibaattribute特性的,且描述為clear的屬性,清空了。固然為了一個(gè)屬性這么做不值得,但假如一個(gè)對(duì)象有70個(gè)屬性的時(shí)候,這么做就值得了。既然能清除屬性的數(shù)據(jù),那么自然就可以為屬性賦值。至于如何實(shí)現(xiàn)反射賦值,信任大家可以舉一反三。反射+特性最頻繁的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論