What are the restrictions on using DynamicObjects?

Feb 27, 2011 at 7:38 PM

I see that the latest version has support for DynamicObjects as models, but what are the limitations/restrictions outside of the Model itself? For instance, I'm trying to use RazorEngine with a simple template like:

    <Paragraph>Recommendation: @Model.Summary.Plan[0].Recommendation[0].Value</Paragraph>

Where the final "Value" property is a dynamic propery on a class drived from DynamicObject. Attempting to use this template results in a "does not contain a definition for 'Value'" error message. Are there some examples of using DynamicObject classes? What are the limitations? Why doesn't my test case above work?


Mar 1, 2011 at 6:52 PM

Never mind. I figured out that it's an oddity with the dynamic stuff in C# in general rather than anything to do with RazorEngine.

Mar 2, 2011 at 7:59 AM

Sorry for the late reply.

What was the resolution in the end?

Mar 3, 2011 at 8:48 PM

Given a derived dynamic class like this:

    public class DynamicTestObject : DynamicObject
        public string StaticProperty { get; set; }

Then using code like this:

    var d = new DynamicTestObject();
    d.StaticProperty = "static";
    d.DynamicProperty = "dynamic";

Will get the error "DynamicTestObject' does not contain a definition for 'DynamicProperty' on the third line. If you change the variable class to explicitly "dynamic" then that problem goes away:

    dynamic d = new DynamicTestObject();
    d.StaticProperty = "static";
    d.DynamicProperty = "dynamic";

So even though DynamicTestObject is derived from a dynamic type, using that derived definition doesn't really get treated as a dynamic type in at least some cases.



Mar 4, 2011 at 8:13 AM
Edited Mar 4, 2011 at 8:14 AM

The problem you are seeing is that you are declaring your variable using var. Var is used for type inference, so at compile time, the compiler essential substitutes var for the static type name. In this case, DynamicTestObject. C# is a statically-typed language, so without using the dynamic keyword, the compiler is attempting to find the DynamicProperty member of DynamicTestObject. If you declare the variable using dynamic, the compiler will accept the call to DynamicProperty and mark it for runtime resolution using late-binding.

In essence if you wan't to use DynamicObject, you have to declare it using dynamic.

Mar 4, 2011 at 4:42 PM

I guess what I found surprising is that "DynamicObject" and "ExpandoObject" don't derive from a base class "dynamic" which is how I'd pictured it working. I'd assumed that the IDE/compiler was doing something like "if (Yourclass is dynamic)" to see if your class was derived from the "dynamic" base class but that's not at all how it apparently works. "DynamicObject" is assignment compatible with "dynamic" but is not derived from it.

Mar 7, 2011 at 8:00 AM

No, they derive from System.Object which all other objects do. It's just that when an instance declared with dynamic is hit in code, the CLR delegates execution to the DLR (the dynamic language runtime) which kicks in, recognises the IDynamicMetaObjectProvider implementation in DynamicObject (or ExpandoObject) and handles the rest. There is no special dynamic base class at all, you're simply using the dynamic keyword in place of the static type name. Much like var which is all compiler magic, dynamic is runtime magic :-)