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() {