添加到 .NET 4的ExpandoObject类允许您在运行时任意设置对象的属性。
Dictionary<string, object>与使用 Hashtable或什至是Hashtable相比,这有什么优势吗?据我所知,这不过是一个哈希表,您可以使用更简洁的语法访问它。
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"]);
使用 ExpandoObject 而不是仅使用任意字典类型可以获得什么 真正的 优势,除了不明显您正在使用将在运行时确定的类型。
由于我写了您所指的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; 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您可以使用EventHandler<dynamic>which 将导致处理程序的第二个参数变为,而不是使用dynamic。
EventHandler
EventHandler<dynamic>
dynamic