浅谈Dynamic 关键字系列之三(上):ExpandoObject, DynamicObject, DynamicMetaObject

简介:

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方法没有被调用??

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




本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/07/05/2098578.html,如需转载请自行联系原作者
目录
相关文章
|
7月前
|
编译器 C#
C#.Net筑基-类型系统②常见类型 --record是什么类型?
`record`在C#中是一种创建简单、只读数据结构的方式,常用于轻量级数据传输。它本质上是类(默认)或结构体的快捷形式,包含自动生成的属性、`Equals`、`ToString`、解构赋值等方法。记录类型可以继承其他record或接口,但不继承普通类。支持使用`with`语句创建副本。例如,`public record User(string Name, int Age)`会被编译为包含属性、相等比较和`ToString()`等方法的类。记录类型提供了解构赋值和自定义实现,如密封的`sealed`记录,防止子类重写。
|
存储 编译器 C#
《More effective C#》第二章 尽量采用隐式属性来表示可变的数据
《More effective C#》第二章 尽量采用隐式属性来表示可变的数据
|
JSON Java 数据库
代码重构实战-将值对象改为引用对象(Change Value to Reference)
一个数据结构中可能包含多个记录,而这些记录都关联到同一个逻辑数据结构。例如,我可能会读取一系列订单数据,其中有多条订单属于同一个顾客。遇到这样的共享关系,既能将顾客信息作为值对象看待,也能将其视为引用对象
107 0
|
Java API
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
JAVA文档并发演示---并发高级对象摘录(Tutorial - Concurrency Lesson--High Level Concurrency Objects)
DHL
|
算法 前端开发 安全
Kotlin StateFlow 搜索功能的实践 DB + NetWork
这篇文章主要来分析一下 PokemonGo 搜索功能的实践
DHL
497 0
Kotlin StateFlow 搜索功能的实践 DB + NetWork
|
存储 iOS开发 开发者
追根问底:Objective-C关联属性原理分析
Objective-C是一种动态性很强的语言,所谓动态能力,也可以理解为运行时能力。对于Objective-C开发者来说,动态性所带来的编程便利无处不在。例如通过Category类别来扩展已有类的功能。可以使已有类拥有新的方法和属性。
170 0
《Drools7.0.0.Final规则引擎教程》番外实例篇——activation-group的多FACT对象
《Drools7.0.0.Final规则引擎教程》番外实例篇——activation-group的多FACT对象
279 0