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; } } }