“动态”类型在通用集合<动态&gt [英] Can the "dynamic" type vary safely in a generic collection<dynamic>?

查看:121
本文介绍了“动态”类型在通用集合<动态&gt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我对此问题的回答,我想检查一下我对C#4即将到来的动态类型的理解。



在这种情况下,我们有一个集合表示从未知数据库表中提取的记录中的字段。较旧的代码(预登录4)要求收集类型为 Object 的项目。除此之外,我想知道当您将 Object 更改为动态时会发生什么。 p>

一方面,我期望因为动态类型的东西都是在运行时完成的,只要程序员没有打错或者关于集合中特定项目的预期类型的​​错误。



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

解决方案

这是Sam的博客中有关缓存政策的相关内容。



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


DLR检查缓存以查看
给定的操作是否已经绑定
与当前集的论据。
所以在我们的例子中,我们将根据1,2和
类型的d执行类型
匹配。如果我们有缓存命中,
然后我们返回缓存的结果。如果
我们没有缓存命中,那么
DLR会检查接收器是否为
一个IDynamicObject。这些人是
本质上是对象,它知道如何
照顾自己的绑定,如
作为COM IDispatch对象,真正的动态
对象,如Ruby或Python,
或实现
的IDynamicObject接口的一些.NET对象。如果是
这些任何一个,那么DLR会将ID $
调用,并要求绑定
操作。



请注意,调用
要绑定的IDO的结果是一个表达式树,
表示绑定的结果。
如果它不是IDO,那么DLR
调用语言绑定器(在
的情况下,C#运行时绑定)绑定
操作。 C#运行时绑定器
将绑定该操作,并将返回
表示绑定的
结果的表达式树。一旦步骤2或3
发生,生成的
表达式树被合并到
缓存机制中,以便任何
后续调用可以针对
缓存而不是正在反弹。


然而,Sam没有提到的就是高速缓存未命中的策略。有两种主要的缓存未命中策略:(1)当参数类型改变时触发高速缓存未命中,(2)当参数标识改变时触发高速缓存未命中。



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


Based on my answer to this question, I want to check something on my understanding of the upcoming dynamic type for C# 4.

In this case, we have a collection that represents fields in a record pulled from an unknown database table. Older code (pre-.Net 4) requires such a collection hold items of type Object. Merits of a such a collection aside, I'm wondering about what happens when you change Object to dynamic.

On the one hand, I expect that since things for dynamic types are all worked out at runtime that everything should be just fine as long as the programmer doesn't make any typos or mistakes about the expected type of a particular item in the collection.

On the other hand, I wonder about the word "all" in the previous sentence. Would the runtime perhaps cache results from the first time a dynamic property is accessed, causing subsequent calls using different types to fail?

解决方案

Here's a relevant bit from Sam's blog that talks briefly about the caching policy.

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.

However, what Sam doesn't mention is exactly what the cache miss policy is. There are two main cache-miss policies: (1) trigger a cache miss when the argument types change, (2) trigger a cache miss when the argument identities change.

Obviously the former is far more performant; working out when we can cache based solely on type is tricky. A detailed exegesis of how all that logic works would take rather a long time; hopefully I or Chris or Sam will do a blog post on it one of these days.

这篇关于“动态”类型在通用集合<动态&gt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆