A very basic question, consider this methods:
public object Foo(object bar) {... }
vs
public dynamic Bar(dynamic bar) {... }
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.
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.