既然我写了你指的那篇MSDN文章,我想我必须要回答这个了。
首先,我预料到了这个问题,这就是为什么我写了一篇博文,展示了 ExpandoObject 的一个或多或少真实的用例:Dynamic in C# 4.0: Introducing the 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;
e?.Invoke(d, new EventArgs());
}
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);
}
}
另外,请记住,没有什么能阻止您以动态方式接受事件参数。换句话说,您可以使用EventHandler<dynamic> 而不是使用EventHandler,这将导致处理程序的第二个参数为dynamic。