静态调用实例方法

Mic*_*Kim 6 c# reflection

假设有一个A带无参数实例方法的类

class A
{
    public A(int x) { this.x = x; }
    private int x;
    public int foo() { return x; }
}
Run Code Online (Sandbox Code Playgroud)

使用反射调用方法很容易:

A a = new A(100);
var method = typeof(A).GetMethod("foo");
var result = method.Invoke(a, new object[0]); // 100
Run Code Online (Sandbox Code Playgroud)

但是,我想调用该方法,就好像它是静态的一样

var staticmethod = Something(typeof(A), "foo");
var result = staticmethod.Invoke(null, new object[] { a });
Run Code Online (Sandbox Code Playgroud)

有什么方法可以得到这个staticmethod吗?

注意:我想要Something是通用的,即A可以是任何类,并且foo可以是任何实例方法.

编辑:说清楚:

课堂上没有静态方法A.

有一个无参数的实例方法叫做foo.

我想调用(使用MethodInfo.Invoke)fooAS如果它是一个静态方法,它将类A作为参数.

EDIT2:我为什么要这样:(帮助你更好地理解)

我有一个静态方法列表,它们针对不同类型执行类似的工作,并且它们存储在字典中Dictionary<Type, MethodInfo> dict.

因此,每当我有一个对象obj并且想要完成这项工作时,我就可以

dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... });
Run Code Online (Sandbox Code Playgroud)

现在我想在其中添加实例方法,但是它需要我记住哪些方法是静态的,哪些方法是实例键,并以不同的方式调用它们:

dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... }); // static methods
dict[obj.GetType()].Invoke(obj, new object[] { param1, param2, ... }); // instance methods
Run Code Online (Sandbox Code Playgroud)

哪个不方便.所以我希望MethodInfo在将它们添加到dict之前从实例方法中获取静态.

编辑3:我不明白为什么这个问题被标记为重复.链接页面不回答我的问题.如果我遗失了什么,请告诉我.

链接页面有几个答案,但它们也是

  1. 要求我知道有多少参数foo,或者
  2. 给出一个以object[]参数为参数的方法,而不是参数列表.

所以它们都不适合这里.

经过一些研究,我发现有一些接近我需要的东西:

 A a = new A(100);
 var method = typeof(A).GetMethod("foo");
 var deleg = Delegate.CreateDelegate(typeof(Func<A, int>), method)
 var result = deleg.DynamicInvoke(new object[] { a }); // 100
Run Code Online (Sandbox Code Playgroud)

在这里,它需要new object[] { a }作为参数.但问题是,因为我不知道foo是怎么样的,我怎么能传递第一个参数Delegate.CreateDelegate呢?

最后编辑:我自己找到了解决方案.谢谢你的帮助!

pok*_*oke 6

但它需要我记住哪些方法是静态的,哪些方法是实例键,并以不同的方式调用它们

无需记住它,因为该方法自己知道:

MethodInfo mi = GetTheMethodFromSomewhere();
object[] args = new object[] { obj, param1, param2, … };
if (mi.IsStatic)
    mi.Invoke(null, args);
else
    mi.Invoke(args[0], args.Skip(1).ToArray());
Run Code Online (Sandbox Code Playgroud)


Mic*_*Kim -1

可以通过创建委托来统一静态方法和实例方法,然后调用DynamicInvoke

Dictionary<Type, Delegate> dict = new Dictionary<Type, Delegate>();

void AddMethod(Type type, String methodName)
{
    var method = type.GetMethod(methodName);
    var types = method.GetParameters().ConvertAll(p => p.ParameterType).ToList();
    if (!method.IsStatic)
        types.Insert(0, type);
    types.Add(method.ReturnType);
    var delegType = Expression.GetFuncType(types.ToArray());
    var deleg = method.CreateDelegate(delegType);
    dict.Add(type, deleg);
}

object GetJobResult(object obj, params object[] additionalParams)
{
    var paramList = additionalParams.ToList();
    paramList.Insert(0, obj);
    return dict[obj.GetType()].DynamicInvoke(paramList.ToArray());
}
Run Code Online (Sandbox Code Playgroud)