C# 動態(tài)查找
如前所述,var關(guān)鍵字本身并不是一個類型,所以并沒有違反C#的“強(qiáng)類型化”方法論。但從C#4開始,—些地方變得沒那么死板。C#4引入了“動態(tài)變量”的概念,顧名思義,動態(tài)變量是類型可變的變量。
引入動態(tài)變量的主要目的是在許多情況下,希望使用C#處理另一種語言創(chuàng)建的對象。這包括與舊技術(shù)的交互操作,例如Component Object Model(COM),也包括處理動態(tài)語言,例如JavaScript、Python和Ruby,這里不詳細(xì)討論其實現(xiàn)細(xì)節(jié),只需要知道,過去使用C#訪問這些語言所創(chuàng)建的對象的方法和屬性需要用到笨拙的語法。例如,假定代碼從JavaScript中獲得一個帶Add()方法的對象,該方法把兩個數(shù)字加在一起,如果沒有動態(tài)查找功能,調(diào)用這個方法的代碼就如下所示:
ScriptObject jsObj = SomeMethodThatGetsTheObject();
int sum = Convert .ToInt32 (jsObj.Invoke("Add_", 2, 3));
ScriptObject類型(這里不深入探討)提供了一種訪問JavaScript對象的方式,但仍不能執(zhí)行如下操作:
int sum = jsObj.Add(2, 3);
動態(tài)查找功能改變了這一切,它允許編寫上述代碼,但如下面幾節(jié)所述,這個功能是有代價的。
另一個可使用動態(tài)查找功能的情形是處理未知類型的c#對象D這聽起來似乎很古怪,但這種情形出現(xiàn)的次數(shù)比我們想象得多。如果需要編寫一璧泛型代碼來處理接收的各種輸入,這也是一項重要功能。處理這種情形的“舊”方法稱為“反射(reflection)”,它涉及使用類型信息來訪問類型和成員?前一章使用了簡單的反射來訪問與類型關(guān)聯(lián)的特性。使用反射訪問類型成員(如方法}的語法非常類似于上述代碼中訪問JavaScript對象的語法,也非常麻煩。
在后臺,動態(tài)查找功能由Dynamic Language Runtime(動態(tài)語言運(yùn)行庫,DLR)支持。與CLR—樣,DLR是.NET 4.7的一部分。DLR的精確描述及其如何簡化交互操作超出了本書的討論范圍,這里僅對如何在C#中使用它感興趣。有關(guān) DLR 的更多內(nèi)容,可以參閱 https:〃docs.microsoft.com/en-us/dotnet/fi'amework/reflection-and-codedom/dynam ic-I anguage-runtime-overview。
動態(tài)類型
C#4引入了 dynamic關(guān)鍵字,以用于定義變量。例如:
dynamic myDynamicVar;
與前面介紹的var關(guān)鍵字不同,的確存在動態(tài)類型,所以在聲明myDynamicVar時,不必初始化它的值。
一旦有了動態(tài)變量,就可以繼續(xù)訪問其成員(這里沒有列出實際獲取變量值的代碼)。
myDynamicVar.DoSomething {"With this !");
無論myDynamicVar實際包含什么值,這行代碼都會編譯。但是,如果所請求的成員不存在,在執(zhí)行這行代碼時會生成一個RuntimeBinderException類型的異常。
實際上,像這樣的代碼提供了一個應(yīng)在運(yùn)行期間應(yīng)用的“處方”。檢查myDynamicVar的值,找到帶一個字符串參數(shù)的DoSomething()方法,并在需耍時調(diào)用它。
點(diǎn)擊加載更多評論>>