I think this is what happens under the hood of Foo((dynamic)a)
:
Asset a = new House(); Type t = typeof(MainClass); t.InvokeMember("Foo", System.Reflection.BindingFlags.InvokeMethod, null, t, new object[] { a });
That will solve Foo(House h)
A quick trip to the monodis.exe file without using reflection (for example, InvokeMember), that is, the dynamic keyword Asset a = new House(); Foo((dynamic)a)
is used instead Asset a = new House(); Foo((dynamic)a)
Asset a = new House(); Foo((dynamic)a)
, this is IL:
IL_0025: ldstr "Foo" IL_002a: ldnull IL_002b: ldtoken MainClass IL_0030: call class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
To a large extent, what your hunch will tell you, “Foo” is a dead sale, that dynamics is an activity.
Now it is sans dynamic, i.e. Asset a = new House(); Foo(a)
Asset a = new House(); Foo(a)
:
IL_0010: ldloc.0 IL_0011: call void class MainClass::Foo(class Asset)
The burnt instruction is largely resolved; it will not change; it always allows Foo(Asset);
Here is the complete code that you can use to analyze dynamic behavior (via monodis.exe or ildasm.exe):
using System; public class MainClass { public static void Main() { Console.WriteLine("Hei"); Asset a = new House(); Foo(a); Foo((dynamic)a); object x = 7; Foo((dynamic)x); } public static void Foo(House h) { Console.WriteLine("House"); } public static void Foo(Asset a) { Console.WriteLine("Asset"); } public static void Foo(int i) { Console.WriteLine("int"); } } public class Asset { } public class House : Asset { }
Conclusion:
Hei Asset House int
This will cause the Foo int to overload, i.e. Foo(int i)
:
object x = 7; t.InvokeMember("Foo", System.Reflection.BindingFlags.InvokeMethod, null, t, new object[] { x } );
It is too:
t.InvokeMember("Foo", System.Reflection.BindingFlags.InvokeMethod, null, t, new object[] { 8 } );
So, to your question, what other option can you use, you can use a method that takes an unexplored object:
public static void FooDynamic(object o) { Type t = typeof(MainClass); t.InvokeMember("Foo", System.Reflection.BindingFlags.InvokeMethod, null, t, new object[] { o } ); }
To call:
Asset a = new House(); FooDynamic(a); // will select Foo House overload int i = 7; FooDynamic(i); // will select Foo int overload
You can also use this API for the code above: public static void Foo(object o)
, then you will need to call Foo as follows:
Asset a = new House(); Foo((object)a);
Given that C # 4 already has the dynamic
capability, it would be difficult for me to use reflection if the developer is still not using C # 3. Thus, instead use the dynamic approach :-)
UPDATE
Why is it slow dynamic
(at least on Mono), when I run this code, it takes about 2 seconds before the letter “B” appears. Dynamic delay is reproducible, even I change the order of the dynamic and reflection code. The delay of reflection is imperceptible, it is faster than dynamic.
using System; public class MainClass { public static void Main() {