[英]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.