zoukankan      html  css  js  c++  java
  • 浅谈Dynamic 关键字系列之三(上):ExpandoObject, DynamicObject, DynamicMetaObject

    http://www.cnblogs.com/LoveJenny/archive/2011/07/05/2098578.html

    ExpandoObject:表示一个对象,该对象包含可在运行时动态添加和移除的成员。

    dynamic dynEO = new ExpandoObject();
    dynEO.number = 10;
    dynEO.Increment = new Action(() => { dynEO.number++; });
    
    Console.WriteLine(dynEO.number);
    dynEO.Increment();
    Console.WriteLine(dynEO.number);
     

    dynEO.number 中number是动态添加属性。

    dynEO.Increment 中Increment 是动态添加的Action 委托。

    枚举ExpandoObject的所有成员:

    foreach (var property in (IDictionary<String, Object>)dynEO)
    {
         Console.WriteLine(property.Key + ": " + property.Value);
    }

    结果如下:

    clip_image002

    接收属性更改的通知:

    static void Main(string[] args)
    {
       ………
        ((INotifyPropertyChanged)dynEO).PropertyChanged += new PropertyChangedEventHandler(Program_PropertyChanged);
        dynEO.Name = "changed";
        dynEO.Name = "another";
    
        Console.ReadLine();
    }
    
    static void Program_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine("属性{0} 已更改", e.PropertyName);
    }

    结果:

    clip_image002[5]

    System.Dynamic.DynamicObject:提供用于指定运行时的动态行为的基类

    新建类DynamicProduct,基本和Product类似:

    image

    可以看到继承了DynamicObject后,可以override 一大堆TryXXX的方法了。

    重点需要了解的是:

    假设sampleObject 就是dynamicObject

    TryGetMember

    在调用 int number = sampleObject.Number.时使用

    TrySetMember

    在调用sampleObject.Number = number 时使用

    TryInvoke

    在调用sampleObject(100) 时使用

    TryInvokeMember

    在调用sampleObject.someMethod(100) 时使用

    完整的代码如下:

    class DynamicProduct : DynamicObject
    {
        public string name;
        public int Id { get; set; }
    
        public void ShowProduct()
        {
            Console.WriteLine("Id={0} ,Name={1}", Id, name);
        }
    
        #region Override DynamicObject 的方法
    
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return base.GetDynamicMemberNames();
        }
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            Console.WriteLine("TryGetMember被调用了,Name:{0}", binder.Name);
            return base.TryGetMember(binder, out result);
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            Console.WriteLine("TrySetMember被调用了,Name:{0}", binder.Name);
            return base.TrySetMember(binder, value);
        }
    
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
            Console.WriteLine("TryInvoke被调用了");
            return base.TryInvoke(binder, args, out result);
        }
    
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Console.WriteLine("TryInvokeMember被调用了,Name:{0}", binder.Name);
            return base.TryInvokeMember(binder, args, out result);
        }
    
        #endregion
    }

    Main函数代码如下:

    static void Main(string[] args)
    {
        dynamic dynProduct = new DynamicProduct();
    
        dynProduct.name = "n1"; //调用TrySetMember方法
        dynProduct.Id = 1;
        dynProduct.Id = dynProduct.Id + 3;
        dynProduct.ShowProduct();
    
        Console.ReadLine();
    }
     

    结果如下:

    clip_image002[7]

    理论上来说,应该输出:

    TrySetMember          :设置name字段

    TrySetMember          :设置Id属性

    TryGetMember          :获取Id属性

    TrySetMember          :设置Id属性

    TryInvokeMember      :调用ShowProduct方法

    Id =4 ,Name = n1

    为什么TryXXX方法没有被调用??

    下篇将解释这个问题,请持续关注..

  • 相关阅读:
    Git 分支开发规范
    小程序技术调研
    弹性布局
    vue 自定义指令的魅力
    记一次基于 mpvue 的小程序开发及上线实战
    mpvue学习笔记-之微信小程序数据请求封装
    微信小程序开发框架 Wepy 的使用
    Hbuilder 开发微信小程序的代码高亮
    luogu3807 【模板】 卢卡斯定理
    luogu1955 [NOI2015] 程序自动分析
  • 原文地址:https://www.cnblogs.com/zkwarrior/p/4753931.html
Copyright © 2011-2022 走看看