C#高级编程9-第12章 动态语言扩展

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声明的成员它是只读的。但是声明成员值是可以修改的.

var t2 = new { Abc = "abc", Value = new { Item= new Person() } };

对于dynamic 而言,它声明后也可以立即使用它,它的成员可读可写,但是它是没有类型的需要编码者判断其来源和属性。

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

ExpandoObject

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();
 
       }
View Code

ViewBag 

public dynamic ViewBag
 
      {
 
          get
 
          {
 
              if (_dynamicViewData == null)
 
              {
 
                  _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
 
              }
 
              return _dynamicViewData;
 
          }
 
      }
View Code

DynamicViewDataDictionary 类的定义为:

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

原文地址:https://www.cnblogs.com/licin/p/6911529.html