C# 静态调用实例方法
假设有一个类C# 静态调用实例方法,c#,reflection,C#,Reflection,假设有一个类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 但是,我
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 });
有什么办法可以得到这个静态方法
注意:我希望某物是通用的,即A
可以是任何类,foo
可以是任何实例方法
编辑:以澄清问题:
类A
中没有静态方法
有一个称为foo
的无参数实例方法
我想调用(使用MethodInfo.invoke
)foo
,就好像它是一个静态方法,以classa
作为参数一样
EDIT2:我为什么想要这个:(帮助你更好地理解)
我有一个静态方法列表,这些方法对不同类型执行类似的工作,它们存储在dictionarydictionary dict
中
因此,每当我有一个objectobj
并想做这项工作时,我都可以
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
这很不方便。因此,在将实例方法添加到dict之前,我想从实例方法中获取staticMethodInfo
EDIT3:我不明白为什么这个问题被标记为重复。链接页面没有回答我的问题。如果我遗漏了什么,请告诉我
链接页面有几个答案,但它们都不是
要求我知道foo
接受多少个参数,或
给出了一个将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
aa=新的A(100);
var方法=类型(A).GetMethod(“foo”);
var deleg=Delegate.CreateDelegate(typeof(Func),方法)
var result=deleg.DynamicInvoke(新对象[]{a});//100
这里,它采用newobject[]{a}
作为参数。但问题是,既然我不知道foo是什么样子,我怎么才能传递Delegate.CreateDelegate
的第一个参数呢
上次编辑:自己找到了解决方案。谢谢你们的帮助,伙计们
但这需要我记住哪些方法是静态的,哪些方法是实例绑定的,并以不同的方式调用它们
不需要记住它,因为方法本身就知道这一点:
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());
}
Dictionary dict=new Dictionary();
void AddMethod(类型类型、字符串方法名)
{
var method=type.GetMethod(methodName);
var types=method.GetParameters().ConvertAll(p=>p.ParameterType.ToList();
如果(!method.IsStatic)
类型。插入(0,类型);
类型。添加(方法。返回类型);
var delegType=Expression.GetFuncType(types.ToArray());
var deleg=method.CreateDelegate(delegType);
dict.Add(type,deleg);
}
对象GetJobResult(对象obj,参数对象[]附加参数)
{
var paramList=additionalParams.ToList();
参数列表。插入(0,obj);
返回dict[obj.GetType()].DynamicInvoke(paramList.ToArray());
}
您可以使用第一个方法调用静态方法。在静态方法的情况下,Invoke
的第一个参数被忽略。@Donnie我认为他不想调用静态方法。他试图像调用静态方法一样调用实例方法。@Donnie我不想调用静态方法,我想要的是使用第二种方法调用实例方法,就像调用静态方法一样调用该方法这到底意味着什么?您试图调用的方法实际上是静态的还是不想创建A
的实例?有一件事你可以做这正是我不想要的。。。你在以不同的方式调用它们,如果不以不同的方式调用它们,你就无法做到这一点。它们必须以不同的方式调用,因为它们是根本不同的。你会想到的其他方法(比如DynamicInvoke
)也会以某种方式封装不同的调用。我不是在讨论调用方法的底层机制,而是如何通过代码调用方法——我的答案看起来很好。顺便说一句,我真的怀疑底层机制是否不同,这只是一个隐式的“this”第一个参数点,因为我会调用很多方法,我需要做任何事情来简化调用代码-我不想写上一千遍,因此,我必须想出一种方法,在添加这些方法时使事情统一起来。在我的情况下,编写另一种方法来封装调用时的差异是行不通的(尽管在我的回答中这是可能的)@MichaelKimDynamicInvoke
看起来不错,但是。您拥有决定是否需要静态调用该方法所需的所有信息。通过创建动态委托来执行额外的路由只会给运行时增加很多不必要的额外负担。您还没有给出分支调用会成为问题的单一原因,如果您只是将其包装在一个方法中,那么使用它没有什么区别;但你会有更好的表现。