简体   繁体   English

动态对象的奇怪行为

[英]Strange behavior of dynamic objects

I have a simple control method DoSomething which receives a json string, converts it to a dynamic object and tries to get the data: 我有一个简单的控制方法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"; 
}

My question is why it is possible to access an indexer when I use an object as a dynamic object at the time when the original type doesn't have an indexer? 我的问题是,当原始类型没有索引器时将对象用作动态对象时,为什么可以访问索引器?

手表窗口

In the first case, you're using all the infrastructure of dynamic - which doesn't just use reflection to find "real" members, but also uses IDynamicMetaObjectProvider to provide support for members which are only known at execution time. 在第一种情况下,您将使用dynamic所有基础结构-不仅使用反射来查找“真实”成员,而且还使用IDynamicMetaObjectProvider为仅在执行时已知的成员提供支持。 This works because when you're using dynamic , the process of binding (working out what a member name means) is performed at execution time instead of at compile time. 之所以起作用,是因为使用dynamic ,绑定过程(确定成员名称的含义)是在执行时而不是在编译时执行的。

In this case, it's the indexer which is being used at execution time - DynamicJsonObject doesn't declare an indexer, but overrides the TryGetIndex method of DynamicObject . 在这种情况下,它正在使用在执行时索引- DynamicJsonObject不声明索引器,但覆盖TryGetIndex的方法DynamicObject The meta-object provider implementation of DynamicObject will route indexer "get" calls via TryGetIndex . DynamicObject的元对象提供程序实现将通过TryGetIndex路由索引器“ get”调用。

A simpler example of this is ExpandoObject : 一个简单的例子是ExpandoObject

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";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM