List 元素有字段但我无法访问它们。 为什么?

我需要遍历List对象。

列表的对象都有值,但由于某种原因,我无法访问任何动态对象字段。 下面是我的调试窗口的屏幕截图:

在此处输入图像描述

在那里你可以看到对象包含字段(例如AliasIdName等)。

我尝试将它转换为IDictionaryExpandoObject ,但无济于事。 我之前没有遇到过这样的事情: dynamic对象存在时无法访问现有字段。

这有什么不对?

该代码抛出一个Microsoft.CSharp.RuntimeBinder.RuntimeBinderException并显示一条消息,指出{"'object' does not contain a definition for 'Name'"}.

创建列表时添加了匿名类型的对象,如下所示:

 return new List(fields.Select(field => new { Id = field.Id, Alias = field.Alias, Name = field.Name, Type = field.Type, Value = field.Value, SortOrder = field.SortOrder })); 

其中fieldsICollection ,一个强类型集合。

告诉部分是例外:

{“’object’不包含’Name’的定义”}。

这表明运行时绑定程序实际上无法访问您在dynamic传递的类型(因为dynamic实际上实际上强制执行可见性规则)。

最可能的原因是你在一个不同的程序集中创建匿名类型,而不是你随后读取它的那个 – 因为匿名类型被声明为internal ,消费程序集无法访问它,导致上面的错误消息。

与通常的运行时绑定程序exception情况相比:

‘<> f__AnonymousType0 ‘不包含’Name’的定义

编辑:

该问题的可能解决方案是在包含匿名类型的程序集上使用InternalsVisibleToAttribute 。 然而,这是代码味道 – 就像任何其他使用InternalsVisibleToAttributeinternal本身一样。

更好的方法是确保你没有实际通过程序集边界传递匿名类型 – 毕竟,它们甚至不应该在它们源自的方法之外使用; 事实上它们基本上是.NET的实现细节 – 它们没有其他方法来做同样的事情。 这可能会在未来版本中发生变化,使InternalsVisibleToAttribute解决方案变得双重不可靠。

您的代码使用dynamic表明您的团队对dynamic如何工作以及如何使用它有错误的假设。 请注意List的实际运行时类型实际上是Listdynamic类型的参数也是如此(它们只是object ,尽管标有DynamicAttribute )。 事实上,这确实是dynamic的 – 它是处理运行时动态调度的一种方式 – 它不是类型或任何东西的属性 ,它只是你实际调用你想要调用的任何东西的方式。 对于C#, dynamic允许您在使用这些动态类型时跳过大多数编译器检查,并生成一些代码来自动处理调度,但所有这些只发生在您实际使用dynamic关键字的方法中 -如果您使用List ,则最终结果将完全相同。

在您的代码中,没有理由不使用简单的静态类型。 除了为类型本身编写代码的努力之外,动态类型并没有真正给你带来任何好处。 如果你的同事不喜欢这样,那么他们应该提出一个更好的解决方案 – 问题非常明显,而且你需要处理这个问题。

更糟糕的是,它明确地隐藏了所有上下文所有类型信息 。 这不是你想要的API,内部与否! 如果要隐藏正在使用的具体类型,为什么不 – 但是您仍然应该公开接口。 我怀疑这就是为什么匿名类型无法实现接口的原因 – 它会鼓励你完全走错路。