gpt4 book ai didi

c# - ExpandoObject 的简单测试失败。谁能解释为什么?

转载 作者:太空狗 更新时间:2023-10-29 23:10:55 24 4
gpt4 key购买 nike

首先是错误信息

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:“System.Collections.Generic.List”不包含“First”的定义在 CallSite.Target(闭包,CallSite,对象)在 System.Dynamic.UpdateDelegates.UpdateAndExecute1(CallSite 站点,T0 arg0)在 ToPropertyDictionaryTests.cs 中的 ClaySharp.Tests.ToPropertyDictionaryTests.TestExpando():第 91 行

测试:

[测试]

public void TestExpando()
{
dynamic root = new ExpandoObject();
root.Name = "Name";

var result = GetExpandos();

root.Child = result;

var first = root.Child.First();

Assert.That(first.Name, Is.EqualTo("Obj1"));
}

private IEnumerable<dynamic> GetExpandos()
{
var toReturn = new List<dynamic>();

dynamic obj1 = new ExpandoObject();
toReturn.Add(obj1);
obj1.Name = "Obj1";

dynamic obj2 = new ExpandoObject();
toReturn.Add(obj2);
obj2.Name = "Obj2";

return toReturn;
}

有趣的是,如果从图片中删除“root”,并针对“result”执行测试,那么它就可以正常工作。

现在是非常奇怪的部分。在返回“toReturn”之前设置调试点。看看这个,它有效

?toReturn.GetType().FullName

“System.Collections.Generic.List`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”

?toReturn

计数 = 2 [0]: {System.Dynamic.ExpandoObject} [1]: {System.Dynamic.ExpandoObject}

?toReturn.First()

{System.Dynamic.ExpandoObject}

就在它被分配给“root”之前,仍然有效

?结果

计数 = 2 [0]: {System.Dynamic.ExpandoObject} [1]: {System.Dynamic.ExpandoObject}

?result.First()

{System.Dynamic.ExpandoObject}

但是分配给root之后,这个就失败了

?root.Child

{System.Collections.Generic.List} [0]: {System.Dynamic.ExpandoObject} [1]: {System.Dynamic.ExpandoObject}

?root.Child.First()

最佳答案

dynamic目前不适用于扩展方法;编译器将无法“动态”绑定(bind)到 LINQ to Objects First方法在运行时被“作为”扩展方法调用。来自语言规范:

7.6.5.2 Extension method invocations

...if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. If expr or any of the args has compile-time type dynamic, extension methods will not apply.

要了解原因,您可能需要阅读 Will the dynamic keyword in C#4 support extension methods?

替换:

var first = root.Child.First();

显式调用静态方法:

var first = Enumerable.First(root.Child);

或者只是使用索引器:

var first = root.Child[0];

编辑:

Interesting part is that if "root" is removed from the picture, and test is performed against the "result" than it works fine.

变量result隐式输入为 IEnumerable<dynamic> ;这是它的编译时(静态)类型。在这种情况下,当您执行 result.First() , 编译器绑定(bind)到 Enumerable.First 没有问题编译时的方法。如果您更改了 result 的编译时类型至 dynamic ,错误会再次出现。

关于c# - ExpandoObject 的简单测试失败。谁能解释为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4913687/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com