被添加到. net 4中的ExpandoObject类允许您在运行时任意地为对象设置属性。

与使用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而不是使用任意的字典类型有什么真正的好处,除了不明显地表明您使用的是将在运行时确定的类型。


当前回答

一个优点是用于绑定场景。数据网格和属性网格将通过TypeDescriptor系统获取动态属性。此外,WPF数据绑定将理解动态属性,因此WPF控件可以比字典更容易地绑定到ExpandoObject。

与动态语言的互操作性(期望使用DLR属性而不是字典条目)在某些场景中也可能需要考虑。

其他回答

这是来自MSDN的一篇很棒的文章,关于使用ExpandoObject为传入的结构化数据(即XML, Json)创建动态特殊类型的示例。

我们还可以将delegate分配给ExpandoObject的动态属性:

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表达式、闭包、动态关键字和DynamicObject类一起,我们可以在c#代码中引入一些函数式编程的元素,这些元素是我们从动态语言如JavaScript或PHP中了解到的。

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

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


有些方法比其他方法更有用,我尽量讲得透彻些。

It may be far more natural to access a collection, in this case what is effectively a "dictionary", using the more direct dot notation. It seems as if this could be used as a really nice Tuple. You can still call your members "Item1", "Item2" etc... but now you don't have to, it's also mutable, unlike a Tuple. This does have the huge drawback of lack of intellisense support. You may be uncomfortable with "member names as strings", as is the feel with the dictionary, you may feel it is too like "executing strings", and it may lead to naming conventions getting coded in, and dealing with working with morphemes and syllables when code is trying understand how to use members :-P Can you assign a value to an ExpandoObject itself or just it's members? Compare and contrast with dynamic/dynamic[], use whichever best suits your needs. I don't think dynamic/dynamic[] works in a foreach loop, you have to use var, but possibly you can use ExpandoObject. You cannot use dynamic as a data member in a class, perhaps because it's at least sort of like a keyword, hopefully you can with ExpandoObject. I expect it "is" an ExpandoObject, might be useful to label very generic things apart, with code that differentiates based on types where there is lots of dynamic stuff being used.


如果你能一次钻到多个层次就好了。

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...

一个优点是用于绑定场景。数据网格和属性网格将通过TypeDescriptor系统获取动态属性。此外,WPF数据绑定将理解动态属性,因此WPF控件可以比字典更容易地绑定到ExpandoObject。

与动态语言的互操作性(期望使用DLR属性而不是字典条目)在某些场景中也可能需要考虑。

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

此外,有了元组语法,你就有了强大的类型推断和inlisense支持

与基于DLR的其他语言进行互操作是我能想到的首要原因。你不能给他们传递Dictionary<string对象>,因为它不是IDynamicMetaObjectProvider。另一个额外的好处是它实现了INotifyPropertyChanged,这意味着在WPF的数据绑定世界中,它还具有Dictionary<K,V>所能提供的额外好处。