静态调用实例方法
Invoke instance method statically
假设有一个 class A
具有无参数实例方法
class A
{
public A(int x) { this.x = x; }
private int x;
public int foo() { return x; }
}
使用反射调用方法很简单:
A a = new A(100);
var method = typeof(A).GetMethod("foo");
var result = method.Invoke(a, new object[0]); // 100
但是,我想像调用静态方法一样调用该方法
var staticmethod = Something(typeof(A), "foo");
var result = staticmethod.Invoke(null, new object[] { a });
有什么办法可以得到这个staticmethod
?
注意: 我希望 Something
是通用的,即 A
可以是任何 class,而 foo
可以可以是任何实例方法。
编辑: 说明:
classA
中没有静态方法。
有一个名为 foo
的无参数实例方法。
我想调用(使用 MethodInfo.Invoke
)foo
好像它是一个静态方法,它以 class A
作为参数。
EDIT2: 为什么我想要这个:(帮助你更好地理解)
我有一个静态方法列表,它们对不同类型执行类似的工作,它们存储在字典中 Dictionary<Type, MethodInfo> dict
。
因此,每当我有一个对象 obj
并且想要完成这项工作时,我可以
dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... });
现在我也想在其中添加实例方法,但这需要我记住哪些方法是静态的,哪些方法是实例绑定的,并以不同的方式调用它们:
dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... }); // static methods
dict[obj.GetType()].Invoke(obj, new object[] { param1, param2, ... }); // instance methods
这很不方便。所以我想从实例方法中获取静态 MethodInfo
,然后再将它们添加到字典中。
EDIT3: 我不明白为什么这个问题被标记为重复。链接页面没有回答我的问题。如果我遗漏了什么,请告诉我。
链接页面有几个答案,但它们要么
- 要求我知道
foo
需要多少个参数,或者
- 给出了一个方法,该方法将
object[]
作为参数,而不是参数列表。
所以 none 适合这里。
经过一些研究,我发现有些东西接近我需要的东西:
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
这里,它以new object[] { a }
作为参数。但问题是,因为我不知道 foo 长什么样,我怎么能传递 Delegate.CreateDelegate
的第一个参数?
上次编辑: 自己找到了解决方案。谢谢你们的帮助!
but it will require me to remember which methods are static and which methods are instance-bond, and invoke them in different ways
不需要记住它,因为方法本身知道:
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());
通过创建一个委托,然后调用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());
}
假设有一个 class A
具有无参数实例方法
class A
{
public A(int x) { this.x = x; }
private int x;
public int foo() { return x; }
}
使用反射调用方法很简单:
A a = new A(100);
var method = typeof(A).GetMethod("foo");
var result = method.Invoke(a, new object[0]); // 100
但是,我想像调用静态方法一样调用该方法
var staticmethod = Something(typeof(A), "foo");
var result = staticmethod.Invoke(null, new object[] { a });
有什么办法可以得到这个staticmethod
?
注意: 我希望 Something
是通用的,即 A
可以是任何 class,而 foo
可以可以是任何实例方法。
编辑: 说明:
classA
中没有静态方法。
有一个名为 foo
的无参数实例方法。
我想调用(使用 MethodInfo.Invoke
)foo
好像它是一个静态方法,它以 class A
作为参数。
EDIT2: 为什么我想要这个:(帮助你更好地理解)
我有一个静态方法列表,它们对不同类型执行类似的工作,它们存储在字典中 Dictionary<Type, MethodInfo> dict
。
因此,每当我有一个对象 obj
并且想要完成这项工作时,我可以
dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... });
现在我也想在其中添加实例方法,但这需要我记住哪些方法是静态的,哪些方法是实例绑定的,并以不同的方式调用它们:
dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... }); // static methods
dict[obj.GetType()].Invoke(obj, new object[] { param1, param2, ... }); // instance methods
这很不方便。所以我想从实例方法中获取静态 MethodInfo
,然后再将它们添加到字典中。
EDIT3: 我不明白为什么这个问题被标记为重复。链接页面没有回答我的问题。如果我遗漏了什么,请告诉我。
链接页面有几个答案,但它们要么
- 要求我知道
foo
需要多少个参数,或者 - 给出了一个方法,该方法将
object[]
作为参数,而不是参数列表。
所以 none 适合这里。
经过一些研究,我发现有些东西接近我需要的东西:
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
这里,它以new object[] { a }
作为参数。但问题是,因为我不知道 foo 长什么样,我怎么能传递 Delegate.CreateDelegate
的第一个参数?
上次编辑: 自己找到了解决方案。谢谢你们的帮助!
but it will require me to remember which methods are static and which methods are instance-bond, and invoke them in different ways
不需要记住它,因为方法本身知道:
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());
通过创建一个委托,然后调用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());
}