对于大师来说,请说服我/我们发生了什么。
List<ExpandoObject> peopleList = new List<ExpandoObject>();
dynamic expandoObj1 = new ExpandoObject();
expandoObj1.id = 1;
expandoObj1.first = "fred";
expandoObj1.last = "krugger";
peopleList.Add(expandoObj1);
dynamic expandoObj2 = new ExpandoObject();
expandoObj2.id = 2;
expandoObj2.first = "george";
expandoObj2.last = "benson";
peopleList.Add(expandoObj2);
//test access the props
var expObj = expandoObj1;
var name = expObj.first;
var expObj2 = peopleList[0] as dynamic;
var name2 = expObj2.first;
IDictionary<string, object> expObj3 = peopleList[0] as ExpandoObject;
var name3 = expObj3["first"];
var expObj4 = peopleList[0] as ExpandoObject;
//var name4 = expObj4.first; //THIS DOESN'T WORK - ExpandoObject does not contain a definition for 'first' etc...
在所有情况下,LEFT-HAND SIDE是System.Dynamic.ExpandoObject; 那么为什么在第四种情况下expObj4,我无法访问属性expObj4.first?
答案 0 :(得分:2)
ExpandoObject是一个密封类,用于将数据存储在字典中。它实现了IDynamicMetaObjectProvider接口,该接口为实现它的类提供动态行为。它还实现了IDictionary接口,它为它提供了类似字典的行为。它应该在编译时检查和验证。
dynamic是一种在编译时不应由编译器检查的类型。它在运行时被检查并中断。在编译时,假定动态实体支持任何操作。所以,当你说它是一个expandoobject时,名为first的字段不会被附加到对象本身。
在这里查看expando对象的源代码
将动态行为视为对象。你可以在那里放任何类型。当您添加到列表时,您将列表添加为动态,但添加的项的固有类型是ExpandoObject。因此,您可以将其强制转换为ExpandoObject。
当你说,
expandoObj1.first = "fred";
与说法相同,
expandoObj1.Add("first", "fred");
使用时
var expObj = expandoObj1;
var name = expObj.first;
您正在以动态形式使用expandoObject。因此,您可以直接访问属性。当您将其强制转换为ExpandoObject类时,您使用的是实际的ExpandoObject类,它将字段存储在Dictionary中,因此点(。)表示法不起作用。
var expObj4 = peopleList[0] as ExpandoObject;
左侧的变量仍然是ExpandoObject,而不是字典。 ExpandoObject通过集合搜索公开其成员。
var name4 = expObj4.Where(t=>t.Key == "first").First().Value;
当你把它投射到字典时,它就像一本字典。
IDictionary<string, object> expObj3 = peopleList[0] as ExpandoObject;
var name3 = expObj3["first"];
当您将其转换为动态时,您可以访问这些键,就像它们是类的属性一样。
答案 1 :(得分:0)
这是因为变量expObj4
声明为ExpandoObject
而不是dynamic
。这是一个重要的区别。
试试这个:
dynamic a = new ExpandoObject();
a.Name = "Test";
这是编译,但以下不是:
ExpandoObject a = new ExpandoObject();
a.Name = "Test";
你明白了:
CS1061'ExploreoObject'不包含'Name'的定义,并且没有扩展方法'Name'可以找到接受类型'ExpandoObject'的第一个参数
您拥有的与此相关的变量是:
神奇的“让我们看看我们是否可以在运行时访问该东西”编译器的代码只有在表达式或变量为dynamic
时才会启动。 ExpandoObject
只是支持的类型。