Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the "dynamic" type vary safely in a generic collection<dynamic>?

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?

like image 869
Joel Coehoorn Avatar asked Feb 01 '10 04:02

Joel Coehoorn


People also ask

Is dynamic type safe?

By this definition, most higher-level languages, including dynamically typed languages, are type safe, because any attempt to use a type incorrectly is guaranteed to cause an error (compile-time or run-time) in them.

How does dynamic typing complicate troubleshooting?

Dynamic languages give you flexibility and the ability to write code faster, but can lead to more error prone code if you're not careful in checking your types.

Which methods are not supported for dynamic types?

Extension methods aren't supported by dynamic code.

Is it better to work with static or dynamic data types?

Static Data structure has fixed memory size whereas in Dynamic Data Structure, the size can be randomly updated during run time which may be considered efficient with respect to memory complexity of the code. Static Data Structure provides more easier access to elements with respect to dynamic data structure.


2 Answers

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.

like image 114
Eric Lippert Avatar answered Sep 17 '22 21:09

Eric Lippert


You can think of dynamic as just syntactic sugar for writing all of the method calls using Reflection and MethodInfo.Invoke() - under the hood it doesn't work exactly like that, but you can think of it working that way, with all of the "calling 1000 methods / sec via dynamic => murdered perf" considerations that go with it.

like image 39
Ana Betts Avatar answered Sep 17 '22 21:09

Ana Betts