Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing dynamic object to C# method changes return type

Tags:

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?

like image 686
Jim Buck Avatar asked Sep 17 '14 13:09

Jim Buck


People also ask

How do you assign a dynamic object in C#?

You can create custom dynamic objects by using the classes in the System. Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class.

Can we pass dynamic as parameter in C#?

Yes, you can do that. As stated in C# 4.0 specification, the grammar is extended to support dynamic wherever a type is expected: type: ...

What is dynamic initialization in C?

Dynamic initialization of object refers to initializing the objects at a run time i.e., the initial value of an object is provided during run time. It can be achieved by using constructors and by passing parameters to the constructors.

What is ExpandoObject in C#?

The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject. sampleMember instead of more complex syntax like sampleObject.


1 Answers

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 time

But any method call is treated as having a return type of dynamic.

like image 187
Jon Skeet Avatar answered Sep 18 '22 12:09

Jon Skeet