C#高級編程9-第12章 動態語言擴展編程
dynamic t = new ExpandoObject(); t.Abc = "abc"; t.Value = 10000; Console.WriteLine(t.Abc); t.Abc = "123"; Console.WriteLine(t.Abc);
dynamic動態類型的值是可讀可寫的,它是編譯型語言,而Javascript是解釋性語言.所以JavaScript定義後能夠引用它。而dynamic定義後,沒法引用它,沒法獲知它的類型是什麼.只有編譯運行時才能得到它的類型.
所以當咱們沒法獲知它的類型時就會出現未知的異常,好比說類型轉換異常、序列化異常、對象或屬性不存在等等。所以對於使用dynamic時經常須要處理系統異常。
對於dynamic動態類型,它僅僅是一種類型,對於var類型它能夠是一種序列化的字符串.
dynamic t = new ExpandoObject(); t.Abc = "abc"; t.Value = 10000; Console.WriteLine(t.Abc); t.Abc = "123"; Console.WriteLine(t.Abc); Console.WriteLine(t.ToString()); var t2 = new { Abc = "abc", Value = 10000 }; Console.WriteLine(t2.ToString());
對於var而言它能夠聲明後當即使用它,可是它的優勢是若是var聲明的成員它是隻讀的。可是聲明成員值是能夠修改的.ide
var t2 = new { Abc = "abc", Value = new { Item= new Person() } };
對於dynamic 而言,它聲明後也能夠當即使用它,它的成員可讀可寫,可是它是沒有類型的須要編碼者判斷其來源和屬性。this
DynamicObejct 是全部動態類的基類,能夠從其繼承以實現本身的動態對象。ExpandoObject 是一個sealed 類,已經封裝好了全部方法。編碼
static void Main(string[] args) { dynamic dynamicObject = new MyDynamicObject(); dynamicObject.FirstName = "Alan"; dynamicObject.LastName = "Yang"; dynamicObject.Age = 28; Action<dynamic> show = (item) => Console.WriteLine("My name is " + item.FirstName + " " + item.LastName + ". I'm " + item.Age + " years old."); dynamicObject.Show = show; dynamicObject.Show(dynamicObject); Console.Read(); } public class MyDynamicObject : DynamicObject { Dictionary<string, object> _dynamicData = new Dictionary<string, object>(); public override bool TryGetMember(GetMemberBinder binder, out object result) { bool success = false; result = null; if (_dynamicData.ContainsKey(binder.Name)) { result = _dynamicData[binder.Name]; success = true; } else { result = "Property Not Found!"; success = false; } return success; } public override bool TrySetMember(SetMemberBinder binder, object value) { _dynamicData[binder.Name] = value; return true; } public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { result = true; dynamic method = _dynamicData[binder.Name]; method(args[0]); return true; } }
ExpandoObjectspa
static void Main(string[] args) { dynamic dynamicObject = new ExpandoObject(); dynamicObject.FirstName = "Alan"; dynamicObject.LastName = "Yang"; dynamicObject.Age = 28; Action<dynamic> show = (item) => Console.WriteLine("My name is " + item.FirstName + " " + item.LastName + ". I'm " + item.Age + " years old."); dynamicObject.Show = show; dynamicObject.Show(dynamicObject); Console.Read(); }
ViewBag debug
public dynamic ViewBag { get { if (_dynamicViewData == null) { _dynamicViewData = new DynamicViewDataDictionary(() => ViewData); } return _dynamicViewData; } }
DynamicViewDataDictionary 類的定義爲:code
using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; namespace System.Web.Mvc { internal sealed class DynamicViewDataDictionary : DynamicObject { private readonly Func<ViewDataDictionary> _viewDataThunk; public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk) { _viewDataThunk = viewDataThunk; } private ViewDataDictionary ViewData { get { ViewDataDictionary viewData = _viewDataThunk(); Debug.Assert(viewData != null); return viewData; } } // Implementing this function improves the debugging experience as it provides the debugger with the list of all // the properties currently defined on the object public override IEnumerable<string> GetDynamicMemberNames() { return ViewData.Keys; } public override bool TryGetMember(GetMemberBinder binder, out object result) { result = ViewData[binder.Name]; // since ViewDataDictionary always returns a result even if the key does not exist, always return true return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { ViewData[binder.Name] = value; // you can always set a key in the dictionary so return true return true; } } }