动态对象的奇怪行为

时间:2015-02-19 10:43:22

标签: c# .net json asp.net-mvc dynamic

我有一个简单的控制方法DoSomething,它接收一个json字符串,将其转换为动态对象并尝试获取数据:

[HttpPost]
public string DoSomething(string jsonStr)  // {"0":null,"1":"loadData"}
{
     // In this case obj.GetType() = System.Web.Helpers.DynamicJsonObject
     object obj = Json.Decode(jsonStr); 

     // Correct, a == "loadData"
     var a = (obj as dynamic)["1"];          

     // Incorrect, compilation exception:
     // "Cannot apply indexing with [] to an expression 
     // of type 'System.Web.Helpers.DynamicJsonObject'"
     var b = (obj as DynamicJsonObject)["1"] 

     return "OK"; 
}

我的问题是,当原始类型没有索引器时,当我将对象用作动态对象时,为什么可以访问索引器?

Watches window

1 个答案:

答案 0 :(得分:2)

在第一种情况下,您使用dynamic的所有基础结构 - 它不仅使用反射来查找“真实”成员,还使用IDynamicMetaObjectProvider为成员提供支持仅在执行时知道。这是有效的,因为当你使用dynamic时,绑定过程(计算成员名称的含义)是在执行时而不是在编译时执行的。

在这种情况下,它是在执行时使用的索引器 - DynamicJsonObject不会声明索引器,而是覆盖DynamicObject DynamicObject方法。 TryGetIndex的元对象提供程序实现将通过ExpandoObject路由索引器“get”调用。

更简单的例子是ExpandoObject foo = new ExpandoObject(); // This is invalid; the compiler can't find a Property member foo.Property = "broken"; dynamic bar = foo; // This is fine; binding is performed at execution time. bar.Property = "working";

{{1}}