扩展对象 添加到 .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"]);

什么 真实的 使用 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;

       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);
   }
}

其他提示

一个优点是用于绑定方案。数据网格和财产电网将拿起通过TypeDescriptor系统的动态特性。此外,WPF数据绑定将了解动态属性,因此WPF控件可以更容易地结合到ExpandoObject比字典。

互操作性动态语言,这将在期望DLR特性,而不是字典条目,也可以是考虑在某些情况下。

对我来说,真正的好处是完全不费力的数据从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>可以为您提供的好处。

这是关于编程的方便。我能想象这个对象写入潦潦草草的程序。

我认为这将有句法受益,因为你不再被使用字典“伪造”动态添加属性。

也就是说,用动态语言我想互操作。

这是伟大的例子 MSDN 文章 关于使用 扩展对象 用于为传入的结构化数据(即 XML、Json)创建动态临时类型。

我们还可以将委托分配给 扩展对象的动态属性:

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

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

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

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

有一些情况下,这是很方便的。我会用它例如模块化外壳。每个模块定义了它自己的配置对话框databinded到它的设置。我为它提供ExpandoObject因为它的DataContext并保存在我的配置存储的值。这样的配置对话框作家只是必须绑定到一个值,它会自动创建并保存。 (并且提供给模块当然使用这些设置)

这是简单地比字典使用更容易。但每个人都应该知道,在内部它仅仅是一个字典。

这就像LINQ只是语法糖,但它使事情更容易,有时

那么直接回答你的问题:这是比较容易写,更容易阅读。但在技术上它本质上是一个Dictionary<string,object>(你甚至可以将它转换成一个列出值)。

var obj = new Dictionary<string, object>;
...
Console.WriteLine(obj["MyString"]);

我认为这只有效,因为所有东西都有一个 ToString(),否则你必须知道它的类型并将“对象”转换为该类型。


其中一些比其他更有用,我试图做到彻底。

  1. 使用更直接的点表示法来访问集合(在本例中实际上是“字典”)可能要自然得多。

  2. 看起来这似乎可以用作一个非常好的元组。您仍然可以称您的成员为“Item1”、“Item2”等...但现在你不必这样做,它也是可变的,与元组不同。这确实有一个巨大的缺点,即缺乏智能感知支持。

  3. 您可能对“成员名称作为字符串”感到不舒服,就像字典的感觉一样,您可能觉得它太像“执行字符串”,并且它可能会导致命名约定被编码,并处理语素和当代码尝试理解如何使用成员时的音节:-P

  4. 您可以为 ExpandoObject 本身或仅为其成员赋值吗?与dynamic/dynamic[]进行比较和对比,使用最适合您需求的一个。

  5. 我不认为dynamic/dynamic[]在foreach循环中工作,你必须使用var,但可能你可以使用ExpandoObject。

  6. 您不能使用dynamic作为类中的数据成员,也许是因为它至少有点像关键字,希望您可以使用ExpandoObject。

  7. 我希望它“是”一个 ExpandoObject,可能有助于将非常通用的事物分开,并使用根据使用大量动态内容的类型进行区分的代码。


如果您可以同时深入到多个级别,那就太好了。

var e = new ExpandoObject();
e.position.x = 5;
etc...

这不是最好的例子,想象一下在您自己的项目中适当的优雅用途。

遗憾的是您无法让代码构建其中一些并将结果推送到智能感知。我不确定这会如何运作。

如果他们和会员一样有价值,那就太好了。

var fifteen = new ExpandoObject();
fifteen = 15;
fifteen.tens = 1;
fifteen.units = 5;
fifteen.ToString() = "fifteen";
etc...

valueTuples后,有什么用ExpandoObject类的? 这6行代码ExpandoObject:

dynamic T = new ExpandoObject();
T.x = 1;
T.y = 2;
T.z = new ExpandoObject();
T.z.a = 3;
T.b= 4;

可以写在一行与元组:

var T = (x: 1, y: 2, z: (a: 3, b: 4));

除了与元组语法你有强大的类型推断和intlisense支持

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top