【问题标题】:Strange behavior of dynamic objects动态对象的奇怪行为
【发布时间】:2015-04-20 16:08:18
【问题描述】:

我有一个简单的控制方法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"; 
}

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

【问题讨论】:

  • @CodeCaster:这是一个非常糟糕的简短回答,内部表示根本不一定相关。您可以编写一个具有动态行为的类,该类响应索引器调用而无需任何地方的字典。此外,这并不能解释编译时/执行时绑定的差异。
  • 我决定一个 obj 在运行时具有相同的类型。我不明白它是如何工作的,为什么它会显示不同的对象行为?
  • 我不明白你的评论,我很害怕 - 我希望我的回答已经解释了......基本上这就是动态绑定的全部内容。
  • @JonSkeet 我的意思是 obj 在所有情况下都继承了 IDynamicMetaObjectProvider 。无论我使用 (obj as dynamic) 还是 (obj as DynamicJsonObject) 都是同一个对象。为什么在第一种情况下我有索引器访问权限而在另一种情况下没有?
  • 是同一个对象,但是当编译时类型为dynamic时,这意味着绑定是在执行时完成的。见msdn.microsoft.com/en-us/library/dd264741.aspx

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


【解决方案1】:

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

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

一个更简单的例子是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";

【讨论】:

  • 好的。你的意思是(obj as dynamic)["1"] 看起来不像 MSIL 中的索引器调用?
  • @dyatchenko:确实没有。看看吧!
  • 好的。我想我明白了。 (obj as dynamic)["1"] - 它不是索引器调用,它被转换为 IDynamicMetaObjectProvider 方法调用,对吧?如果可以,谢谢!
  • @dyatchenko:嗯,它是源代码中的索引器调用,但它通过动态类型编译为调用。 (查看 IL 了解详细信息。)
猜你喜欢
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
相关资源
最近更新 更多