zoukankan      html  css  js  c++  java
  • 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
    
    
  • 相关阅读:
    强制位与冒险位
    完美图解教程 Linux环境VNC服务安装、配置与使用
    Linux 最常用命令
    return 与 exit()的区别return退出本函数,exit()退出整个程序
    Linux标准目录配置(转自鸟哥)
    Hadoop C访问
    Shell学习总结
    为 Linux 应用程序编写 DLL(在仅仅只会编写插件的时候为什么要编写整个应用程序?)
    SteveY对Amazon和Google平台的长篇大论
    gcc环境变量基础
  • 原文地址:https://www.cnblogs.com/licin/p/6911529.html
Copyright © 2011-2022 走看看