Dynamic动态类型
什么是動態類型
了解什么是動態類型首先我們了解靜態類型,在我們平時定義一個int i=1就是靜態類型,靜態類型就是我們在沒有編譯的時候已經明確的知道他是一個int類型,動態語言是我們在運行時才會知道的類型。所以我們在編寫動態類型的時候是無法使用vs的智能提示,因為編譯器也不知道他是一個什么類型。
dynamic i = 1; Console.WriteLine(i.GetType()); dynamic str = "1"; Console.WriteLine(str.GetType());引用一張結構圖
從圖中可以看出,DLR是建立在CLR的基礎之上的,其實動態語言運行時是動態語言和C#編譯器用來動態執行代碼的庫,它不具有JIT編譯,垃圾回收等功能。DLR通過它的綁定器(binder)和 調用點(callsite),元對象來把代碼轉換為表達式樹,然后再把表達式樹編譯為IL代碼,最后 由CLR編譯為本地代碼(DLR就是幫助C#編譯器來識別動態類型)。
dynamic和var區別
var關鍵字不過是一個指令,它告訴編譯器根據變量的初始化表達式來 推斷類型。(記住var并不是類型),而dynamic是類型,但是編譯時不屬于CLR 類型(指的int,string,bool,double等類型,運行時肯定CLR類型中一種的),它是包含了 System.Dynamic.DynamicAttribute特性的System.Object類型,但與object又不一樣,不一樣主要體現在動態類型不會在編譯時時執行顯式轉換
使用動態類型的優點
1.減少強類型的轉換
2.延遲加載
3.調用C#類型中不存在的其他語言的類型
使用動態類型的缺點
1.沒有智能提示
2.需要預先知道接收的數據結構
動態語言的約束
1不能用動態類型作為擴展方法的參數
2委托和動態類型不能隱式轉換
3動態類型不能調用構造函數和靜態方法
4類型聲明和泛型類型參數
5類型聲明和泛型類型參數不能聲明一個基類為dynamic的類型,也不能將dynamic用于類型參數的約束,或作為類型 所實現的接口的一部分
實現動態行為
我們實現動態行為微軟給我們提供了三種方式,下面我們來試一試:
使用ExpandObject
static void Main(string[] args) {dynamic expand = new ExpandoObject();//動態為expand類型綁定屬性expand.Name = "王麻子";expand.Age = 24;//動態為expand類型綁定方法expand.AddMethod = (Func<int, string>)(x => $"你傳進來的是{x}"); //調用expand類型的屬性和方法 Console.WriteLine($"姓名:{expand.Name}\n年齡:{expand.Age}\n綁定方法:{expand.AddMethod(666)}");Console.Read(); } 姓名:王麻子 年齡:24 綁定方法:你傳進來的是666?
使用DynamicObject
class DynamicType : DynamicObject {// 重寫方法, public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result){Console.WriteLine(binder.Name + "方法被調用");result = null;return true;}public override bool TrySetMember(SetMemberBinder binder, object value){Console.WriteLine(binder.Name + "屬性被設置," + "設置的值為:" + value);return true;} }class Program {static void Main(string[] args){dynamic dynamicobj = new DynamicType();dynamicobj.CallMethod();dynamicobj.Name = "王麻子";dynamicobj.Age = "24";Console.Read();} } CallMethod方法被調用 Name屬性被設置,設置的值為:王麻子 Age屬性被設置,設置的值為:24?
實現IDynamicMetaObjectProvider接口
class Metadynamic : DynamicMetaObject {internal Metadynamic(Expression expression, DynamicType2 value) : base(expression, BindingRestrictions.Empty, value) { }//重寫響應成員調用方法 public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args){//獲得真正的對象 DynamicType2 target = (DynamicType2)base.Value;Expression self = Expression.Convert(base.Expression, typeof(DynamicType2));var restrictions = BindingRestrictions.GetInstanceRestriction(self, target);//輸出綁定方法名 Console.WriteLine(binder.Name + "方法被調用了");return new DynamicMetaObject(self, restrictions);} } public class DynamicType2 : IDynamicMetaObjectProvider {public DynamicMetaObject GetMetaObject(Expression parameter){Console.WriteLine("開始獲得元數據......");return new Metadynamic(parameter, this);} }class Program {static void Main(string[] args){dynamic dynamicobj2 = new DynamicType2();dynamicobj2.Call();Console.Read();} } 開始獲得元數據...... Call方法被調用了?
總結
以上是生活随笔為你收集整理的Dynamic动态类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅析C#基于TCP协议的SCOKET通信
- 下一篇: 谷歌全球ip地址库