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聲明的成員它是隻讀的。可是聲明成員值是能夠修改的.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;
 
        }
 
    }
View Code

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

ViewBag debug

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

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;
 
        }
 
    }
 
}
View Code
相關文章
相關標籤/搜索