CallMeLaNN
CallMeLaNN

Reputation: 8578

dynamic vs object keyword on method params and return type

A very basic question, consider this methods:

public object Foo(object bar) {... }

vs

public dynamic Bar(dynamic bar) {... }

While practically I don't have method signature like this, this example simplified for brevity to show two things: 'dynamic vs object' keyword in method parameter and return's.

What is the difference between these two methods, does it generate the same IL or any performance impact?

Based on reference/workthrough/example out there that tell dynamic is just like object with added dynamic feature, I guess both are the same thing but only differ based on usage like if I want to add another dynamic properties/methods on the return value. However I still wonder if there is another key things to consider.

Note that if I have a class that has a Bar method like above and implement an interface with a method signature like below (or vice versa), the compiler does not complain anything.

object Bar(object bar);

After about 3 years of the existence, I just has a chance to use dynamic feature in a project like creating dynamic repository to be consumed by Web API and generate (dynamic) JSON.

public interface IRepository
{
    IEnumerable GetAll(string entityName, int skip, int take);
    int Count(string entityName);
    dynamic GetById(string entityName, int key);
    void Add(string entityName, dynamic entity);
    void Remove(string entityName, int key);
}

Where an entity is not concrete and entityName is defined in a db column. I also considering either to use IEnumerable or IEnumerable<dynamic>. Any thought?

Upvotes: 0

Views: 667

Answers (2)

IS4
IS4

Reputation: 13217

dynamic in C# is translated to object in IL.

.method private hidebysig instance object Foo(object bar) cil managed
{...}

.method private hidebysig instance object Bar(object bar) cil managed
{
  .param [0]
  .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
  .param [1]
  .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
  ...
}

The signature stays the same, only the Dynamic attribute is added to the return and first parameter.

If you can change the parameter type from dynamic to object without having to change any other code, do it.

Upvotes: 0

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62002

Depending on the {... } they certainly don't lead to the same IL! Consider:

public object Foo(object bar)
{
  Use(bar);
}

void Use(int i)
{
}
void Use(string s)
{
}
void Use(IConvertible c)
{
}
void Use<T>(IEnumerable<T> e)
{
}
void Use(object o)
{
}

The IL will simply contain a call to the last overload of Use.

But had the parameter been declared as dynamic bar instead, the IL would contain code to start up the very complex overload resolution algorithm. This could lead to any of the overloads being called, or might lead to an error (for example with bar==null, the best overload cannot be determined).

Clearly very different IL. Clearly the performance is worse when we have to do the whole binding when the application runs (dynamic), instead of doing it once and for all when the program is compiled.

It is also clear that the slow and complex code in the dynamic case could be what we really wanted, rather than alway calling the same overload.

Upvotes: 2

Related Questions