我需要循环一个List<dynamic>对象.
列表的对象都有值,但由于某种原因,我无法访问任何动态对象字段.下面是我的调试窗口的屏幕截图:

在那里你可以看到对象包含字段(例如Alias,Id,Name等).
我试了两个强制转换为IDictionary<string, object>和ExpandoObject,无济于事.我之前没有遇到过这样的事情:当dynamic对象存在时无法访问对象中的现有字段.
这有什么不对?
代码抛出Microsoft.CSharp.RuntimeBinder.RuntimeBinderException一条消息说明{"'object' does not contain a definition for 'Name'"}.
创建列表添加了匿名类型的对象,如下所示:
return new List<dynamic>(fields.Select(field => new
{
Id = field.Id,
Alias = field.Alias,
Name = field.Name,
Type = field.Type,
Value = field.Value,
SortOrder = field.SortOrder
}));
Run Code Online (Sandbox Code Playgroud)
这里fields是一个ICollection<Field>,一个强类型集合.
Lua*_*aan 10
告诉部分是例外:
{"'object'不包含'Name'的定义"}.
这表明运行时绑定程序实际上无法访问您传入的类型dynamic(因为dynamic实际上强制执行可见性规则).
最可能的原因是你在一个不同的程序集中创建匿名类型,而不是你随后读取它的那个 - 因为声明internal了匿名类型,消费程序集无法访问它,导致上面的错误消息.
与通常的运行时绑定程序异常情况相比:
'<> f__AnonymousType0 <string>'不包含'Name'的定义
编辑:
该问题的可能解决方案是使用InternalsVisibleToAttribute包含匿名类型的程序集.然而,这是代码味道 - 就像任何其他用途InternalsVisibleToAttribute或internal本身一样.
一种更好的方法是确保你不会在程序集边界上实际传递匿名类型 - 毕竟,它们甚至不应该在它们源自的方法之外使用; 事实上它们基本上是.NET的实现细节 - 他们没有其他方法来做同样的事情.这可能会在未来的版本中发生变化,使InternalsVisibleToAttribute解决方案倍加不可靠.
您的代码使用方式dynamic表明您的团队对如何dynamic工作以及如何使用它们有错误的假设.需要注意的实际运行时类型如何List<dynamic>实际上是List<object>.类型的参数也是如此dynamic(object虽然标记为,但它们也是如此DynamicAttribute).事实上,这实际上就是dynamic- 它是处理运行时动态调度的一种方式 - 它不是类型或任何东西的属性,它只是你实际调用你试图调用的任何东西的方式.对于C#,dynamic允许您在使用这些动态类型时跳过大多数编译器检查,并生成一些代码来自动处理调度,但所有这些只发生在您实际使用dynamic关键字的方法中- 如果您使用后List<object>,最终结果将完全相同.
在您的代码中,没有理由不使用简单的静态类型.除了努力编写类型本身之外,动态类型并没有真正给你带来任何好处.如果你的同事不喜欢这样,那么他们应该提供一个更好的解决方案 - 问题非常明显,而且你需要处理这个问题.
更糟糕的是,它明确隐藏了所有上下文,所有类型信息.这不是你想要的API,内部与否!如果要隐藏正在使用的具体类型,为什么不 - 但是您仍然应该公开接口.我怀疑这就是匿名类型无法实现接口的原因 - 它会鼓励你完全走错路.