C# · 12月 27, 2021

c# – “动态”类型可以在通用集合中安全地变化吗?

根据我对 this question的回答,我想检查一下我对C#4即将推出的动态类型的理解.

在这种情况下,我们有一个集合,表示从未知数据库表中提取的记录中的字段.较旧的代码(预登录4)需要这样一个收集类型为Object的项目.除了这样一个收藏的优点,我想知道当您将对象更改为动态时会发生什么.

一方面,我期望,因为动态类型的东西都是在运行时完成的,只要程序员没有对集合中特定项目的预期类型做出任何打字或错误,那么所有内容都应该是正常的.

另一方面,我不知道上一句中的“全部”一词.运行时可能会从第一次访问动态属性缓存结果,导致使用不同类型的后续调用失败?

解决方法 这是Sam的博客中有关缓存策略的相关内容.

http://blogs.msdn.com/samng/archive/2008/10/29/dynamic-in-c.aspx

The DLR checks a cache to see if the
given action has already been bound
against the current set of arguments.
So in our example,we would do a type
match based on 1,2,and the runtime
type of d. If we have a cache hit,
then we return the cached result. If
we do not have a cache hit,then the
DLR checks to see if the receiver is
an IDynamicObject. These guys are
essentially objects which kNow how to
take care of their own binding,such
as COM IDispatch objects,real dynamic
objects such as Ruby or Python ones,
or some .NET object that implements
the IDynamicObject interface. If it is
any of these,then the DLR calls off
to the IDO and asks it to bind the
action.

Note that the result of invoking the
IDO to bind is an expression tree that
represents the result of the binding.
If it is not an IDO,then the DLR
calls into the language binder (in our
case,the C# runtime binder) to bind
the operation. The C# runtime binder
will bind the action,and will return
an expression tree representing the
result of the bind. Once step 2 or 3
have happened,the resulting
expression tree is merged into the
caching mechanism so that any
subsequent calls can run against the
cache instead of being rebound.

不过,山姆没有提到,正是高速缓存未命中的政策.有两个主要的缓存未命中策略:(1)当参数类型改变时触发高速缓存未命中,(2)当参数标识改变时触发高速缓存未命中.

显然,前者的表现要好得多;当我们可以仅基于类型缓存时,工作是棘手的.所有这些逻辑的工作将会花费很长时间的详细解释;希望我或Chris或Sam在这些日子之一做一个博客文章.