CSharp - ExpandoObject真正的好处是什么?

  显示原文与译文双语对照的内容

在在 runtime, ExpandoObject 类可以被添加到. NET 4使你可以任意地设置属性到一个主体

对于使用 Dictionary<string,object>,或者甚至是哈希表,有什么好处? 据我所知,这只是一个哈希表,你可以使用更简洁的语法访问它。

例如为什么:


dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString ="Foo";
Console.WriteLine(obj.MyString);

真正的更好,或者本质上不同于:


var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] ="Foo";

Console.WriteLine(obj["MyString"]);

在 runtime, 什么真实以外的优势在于通过使用ExpandoObject获取,而不是只使用一个任意的字典类型,确定不被明显,那就是你正在使用一个类型以将要React

时间:

因为我写的MSDN文章要引用,我想,我得回答这个地址。

首先,我预料到了这个问题,这就是我写博客文章的原因,它显示了ExpandoObject的实际使用情况: 动态在 C# 4.0中: 介绍 ExpandoObject 。

很快,ExpandoObject可以帮助你创建复杂的分层对象。 例如假设你在字典中有一个字典:


Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] ="WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

层次越深,代码越丑。 使用 ExpandoObject,它保持优雅易读。


dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State ="WA";
Console.WriteLine(expando.Address.State);

第二,就像已经指出的,ExpandoObject实现了INotifyPropertyChanged接口,它提供了对属性的更多控制,而不是字典。

最后,你可以像下面这样向ExpandoObject添加事件:


class Program
{

 static void Main(string[] args)
 {
 dynamic d = new ExpandoObject();

//Initialize the event to null (meaning no handlers)
 d.MyEvent = null;

//Add some handlers
 d.MyEvent += new EventHandler(OnMyEvent);
 d.MyEvent += new EventHandler(OnMyEvent2);

//Fire the event
 EventHandler e = d.MyEvent;

 if (e!= null)
 {
 e(d, new EventArgs());
 }

//We could also fire it with...
//d.MyEvent(d, new EventArgs());

//...if we knew for sure that the event is non-null.
 }

 static void OnMyEvent(object sender, EventArgs e)
 {
 Console.WriteLine("OnMyEvent fired by: {0}", sender);
 }

 static void OnMyEvent2(object sender, EventArgs e)
 {
 Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
 }
}

真正的好处是来自XAML的完全毫不费力的数据绑定:


public dynamic SomeData { get; set; }


SomeData.WhatEver ="Yo Man!";


 <TextBlock Text="{Binding SomeData.WhatEver}"/>

DLR 建立的其他语言互操作是 #1的原因,我可以考虑。 你不能传递 Dictionary<string, object>,因为它不是 IDynamicMetaObjectProvider 。 另一个好处是它实现了 INotifyPropertyChanged,这意味着在WPF的数据绑定世界中,它还增加了比 Dictionary<K,V> 能够提供的好处。

在某些情况下,这种情况很方便。 我将使用它作为一个模块化外壳,例如。 每个模块定义它自己的配置对话框databinded到它的设置。 我提供了一个 ExpandoObject,因为它是 Datacontext,并将它的保存在我的配置存储中。 这样,配置对话框编写器就必须绑定到一个值,并自动创建并保存。 ( 并提供给模块以使用这些设置)

使用字典比字典简单。 但大家都应该注意到,在内部它只是一个字典。

它就像LINQ的语法糖,但它让事情变得更容易。

因此,直接回答你的问题: 写起来更容易,更容易阅读。 但从技术上讲它本质上是一个 Dictionary<string,object> ( 你甚至可以将它的转换为一个 List 值) 。

这是来自伟大 MSDN文章的示例关于使用 ExpandoObject 为传入结构化数据( 例如 XML,Json ) 创建动态ad-hoc类型。

我们也可以指派委托给 ExpandoObject的动态特性:


dynamic person = new ExpandoObject();
expando.FirstName ="Dino";
expando.LastName ="Esposito";

person.GetFullName = (Func<String>)(() => { 
 return String.Format("{0}, {1}", 
 person.LastName, person.FirstName); 
});

var name = person.GetFullName();
Console.WriteLine(name);

因此它允许我们在运行时将一些逻辑注入动态对象。 因此,除了lambda表达式,闭包,动态关键字和 DynamicObject类,我们可以将函数编程中的一些元素引入 C# 代码,我们将动态语言作为JavaScript或者 PHP 。

...