I created a class that inherits DynamicObject
and want to create a static method that can create new instances with pre-determined properties (stored in the Dictionary
).
public class CustomDynamic : DynamicObject
{
protected Dictionary<string, object> InnerDictionary;
public static T Create<T>(Dictionary<string, object> dictionary) where T : CustomDynamic , new()
{
return new T
{
InnerDictionary = dictionary
};
}
}
Usage:
dynamic d = new Dictionary<string, object>();
var realPlayer = CustomDynamic.Create<Player>(d as Dictionary<string, object>);
var dynaPlayer = CustomDynamic.Create<Player>(d);
realPlayer // Player type according to VS2013
dynaPlayer // dynamic type according to VS2013
Since there is only one method signature, why does passing in a dynamic return a dynamic object? Or is actually just Visual Studio 2013 getting confused?
This is because almost any operation involving a dynamic value is resolved dynamically at execution time. There are no exceptions made for cases where actually there's only one method present at compile-time; the language is simpler that way. (For certain calls, the compiler does perform enough resolution at compile-time to ensure that there is at least one method with a suitable number of parameters - this is specified in the C# 5 spec in section 7.5.4, but that doesn't affect the effective return type.)
From the C# 5 spec, section 7.6.5:
An invocation-expression is dynamically bound if at least one of the following holds:
- The primary-expression has compile-time type
dynamic
.- At least one argument of the optional argument-list has compile-time type
dynamic
and the primary-expression does not have a delegate type.In this case the compiler classifies the invocation-expression as a value of type
dynamic
. [...]
There are a few operations involving dynamic values which still have a non-dynamic overall type. For example:
d is Foo
is always bool
d as Foo
is always Foo
new Foo(d)
is always Foo
even though the exact constructor to use is determined at execution timeBut any method call is treated as having a return type of dynamic
.
See more on this question at Stackoverflow