Pierwsze rozwiązanie (dość brzydkie niestety) jakie mi przychodzi do głowy:
Console.WriteLine(dynm.GetType().GetMethod("Add").Invoke(null, new object[] { 10, 10 }));
Można to lekko poprawić tworząc metodę pomocniczą:
static class StaticHelper {
public static object InvokeStatic(this object obj, string method, params object[] args) {
return obj.GetType().GetMethod(method).Invoke(null, args);
}
}
object obj = dynm; // już nie potrzeba dynamic
Console.WriteLine(obj.InvokeStatic("Add", 10, 10));
Poszukałem rad u mądrych w sieci, znalazłem ciekawe rozwiązanie (wersja praktycznie oryginalna, zmiany głównie w formatowaniu):
http://blogs.msdn.com/b/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx
public class StaticMembersDynamicWrapper : DynamicObject {
Type type;
public StaticMembersDynamicWrapper(Type type) {
this.type = type;
}
// Handle static properties
public override bool TryGetMember(GetMemberBinder binder, out object result) {
PropertyInfo prop = type.GetProperty(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (prop == null) {
result = null;
return false;
}
result = prop.GetValue(null, null);
return true;
}
// Handle static methods
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
MethodInfo method = type.GetMethod(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (method == null) {
result = null;
return false;
}
result = method.Invoke(null, args);
return true;
}
}
Działa to tak:
dynamic dynm = Activator.CreateInstance(m);
dynamic staticDynm = new StaticMembersDynamicWrapper(dynm.GetType());
Console.WriteLine(staticDynm.Add(10, 10));
Tzn. otrzymujesz dynamiczny obiekt za pomocą którego możesz wołać metody statyczne z klasy. Niestety, dla odmiany nie możesz wołać metod niestatycznych (cały wrapper działa na poziomie typów)...
Moja próba modyfikacji, która UMnieDziała(tm):
public class StaticWrapper : DynamicObject {
object obj;
public StaticWrapper(object wrapped) {
this.obj = wrapped;
}
// Handle static properties
public override bool TryGetMember(GetMemberBinder binder, out object result) {
PropertyInfo prop = obj.GetType().GetProperty(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
if (prop == null) {
result = null;
return false;
}
result = prop.GetValue(obj, null);
return true;
}
// Handle static methods
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
MethodInfo method = obj.GetType().GetMethod(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
if (method == null) {
result = null;
return false;
}
result = method.Invoke(obj, args);
return true;
}
}
Użycie:
dynamic dynm = new StaticWrapper(Activator.CreateInstance(m));
Console.WriteLine(staticDynm.Add(12, 10));
Do wyboru, do koloru.