Expando Object 介绍 - Dotnet 4.0






2.14/5 (13投票s)
这篇短文将重点介绍 Expando Object 的一些特性
引言
Dotnet 4.0 框架中另一个新增的功能是 Expando object。它在 System.Core 程序集中定义,属于 System.Dynamic 命名空间。
Intellisense 将 Expando object 描述为
Expando Object – 内部视图
深入了解 Expando Object 会发现以下内容
Expando 类不能被继承,因为它被密封了。它实现了六个不同的接口。其中,以下两个需要特别注意
IDynamicMetaObjectProvider
我们知道,任何可以在运行时绑定其操作的对象都必须实现 IDynamicMetaObjectProvider。Expando object 也是如此。
因此,dynamic dyn = new ExpandoObject(); 是一个完全有效的语句。
INotifyPropertyChanged
每当添加或修改新成员时,该类都会引发 PropertyChange 事件。
使用代码
示例 1:添加成员
考虑以下程序
dynamic dyn = new ExpandoObject(); //Members additon dyn.Member1 = "Some Member"; dyn.Member2 = 2; Console.WriteLine(dyn.Member1); Console.WriteLine(dyn.Member2);
我们只是向 ExpandoObject 添加了两个成员。真的很简单。
示例 2:从 Expando 集合中读取和写入
此代码片段将展示如何向 Expando 集合赋值
ListexpandoList = new List (); //Writing to Expando Collection for (int i = 2; i --> 0;) { dynamic dynObject = new ExpandoObject(); dynObject.Prop1 = i; dynObject.Prop2 = "String Property" + i; dynObject.Prop3 = AddDictionaryObject (i); expandoList.Add(dynObject); } //Adding a dictionary object private static Dictionary AddDictionaryObject(int i) { Dictionary dict = new Dictionary (); dict.Add(i, "Value" + i.ToString()); return dict; }
首先,我们实例化一个新的 ExpandoObject 集合。
列表
然后,使用新的“Goes To”运算符,我们将两个项目填充到集合中。
行 dynamic dynObject = new ExpandoObject(); 确保 ExpandoObject 被分配给动态对象,此后我们可以动态地向其添加属性,DLR 将在运行时检查这些属性。我们还有一个属性(这里是 Prop3),它的类型是 Dictionary < int, string >
代码非常直观。
下一部分展示了如何从刚刚创建的 Expando 集合中读取值
//Reading from Expando Collection foreach (dynamic d in expandoList) { Console.WriteLine("Reading Collection {0} Values", d.Prop1); Console.WriteLine("Prop1 value is: {0}",d.Prop1); Console.WriteLine("Prop2 value is: {0}", d.Prop2); foreach (dynamic dic in d.Prop3) { Console.WriteLine("The key is {0} and it's value is {1}",dic.Key,dic.Value); } Console.WriteLine(Environment.NewLine); Console.WriteLine("-----------------------------------------------------------"); }
可以理解的是,我们正在循环遍历 Expando 集合,并且由于每个项目的类型都是 dynamic,我们可以简单地调用属性名称。但是,属性是否有效将在运行时进行检查。
示例 3:添加 Action 和 Func 委托
考虑以下:
情况 1:为回调添加 Action 委托
dynamic dynObj= new ExpandoObject(); //Add Action Delegate dynObj.Action = new Action(() => { Console.WriteLine("Helo From Action Delegate"); }); //Invoke the Action method dynObj.Action();
不多说… 只是在运行时分配 Action 委托,并调用它进行简单的回调。
情况 2:为回调添加 Func 委托
//Add Func delegate dynObj.Func = new Func((a, res, str) => Calci(a,res,str)); //Invoke the Func Method Console.WriteLine("The {0} operation yields {1}", "+", dynObj.Func(12, 4, "+"));
Calci 函数在这里
private static int Calci(int num1, int num2, string op) { int result = 0; switch (op) { case "+": result = num1 + num2; break; case "-": result = num1 - num2; break; case "*": result = num1 * num2; break; case "/": result = num1 / num2; break; } return result; }
这展示了我们如何使用 Func 委托进行简单的算术运算。
示例 4:通知属性更改事件
如上所述,Expando Object 实现了 INotifyPropertyChanged 接口,该接口位于 System.ComponentModel 命名空间中。
这意味着,每当我们向 Expando Object 添加新属性或更改现有属性的值时,应该触发 PropertyChanged 事件处理程序。让我们看看如何做到这一点
dynamic dynObject = new ExpandoObject(); ((INotifyPropertyChanged)dynObject).PropertyChanged += new PropertyChangedEventHandler(Program_PropertyChanged); dynObject.Property1 = 10; //Now change the value dynObject.Property1 = 20;
而 PropertyChanged 事件处理程序如下
static void Program_PropertyChanged ( object sender , PropertyChangedEventArgs e ) { Console.WriteLine("Property {0} with value {1}", e.PropertyName, ((dynamic)sender).Property1); }
在这里,我们只是定义了一个属性 Property1,并将初始值设置为 10。接下来,我们将属性值更改为 20。结果是
示例 5:处理事件
我们可以为 ExpandoObject 定义事件。
要遵循的步骤列在下面
#region Handling Events dynamic dynObjectEvent = new ExpandoObject(); //Just Adding a memeber dynObjectEvent.Value = 10; //Step 1: Add a member and set it to null first dynObjectEvent.customEventMember = null; //Step 2:Now subscribe dynObjectEvent.customEventMember += new EventHandler(CustomEventHandler); //Step 3: Raise the Event EventHandler eh = dynObjectEvent.customEventMember; if (eh != null) eh.Invoke(dynObjectEvent, EventArgs.Empty); //or eh(dynObjectEvent, EventArgs.Empty); #endregion
事件处理程序定义如下
static void CustomEventHandler(object sender, EventArgs e) { Console.WriteLine("Custom event handler raised by {0} and has send a value {1}", ((dynamic)sender).customEventMember , ((dynamic)sender).Value); }
可以看出,定义事件是一个三步过程。
步骤 1: 添加一个成员,并首先将其设置为 null
dynObjectEvent.customEventMember = null;
步骤 2: 现在订阅事件
dynObjectEvent.customEventMember += new EventHandler(CustomEventHandler);
步骤 3: 触发事件
EventHandler eh = dynObjectEvent.customEventMember; if (eh != null) eh.Invoke(dynObjectEvent, EventArgs.Empty);
输出为:
结论
在这个简短的教程中,我们已经看到了 Expando Object 的一些好处。
非常感谢您对该主题的评论,以便改进该主题。
感谢阅读本文。