我有一个包含一些常见错误处理代码的类,我想传递要调用的方法和参数,但我不太能想出语法。我想做的事情大致是这样的:
private void InvokeHelper(Delegate method, params object[] args)
{
bool retry = false;
do
{
try
{
method.DynamicInvoke(args);
retry = false;
}
catch (MyException ex)
{
retry = HandleException(ex);
}
} while (retry);
}
然后能够执行以下操作:
InvokeHelper(foo.MethodA, a, b, c);
InvokeHelper(foo.MethodB, x, y );
将 foo.MethodA 和 foo.MethodB 转换为 System.Delegate 时会出现编译器错误。我想出了下面的解决方法(实际上我更喜欢它,因为这样我就可以对我的方法的参数进行类型检查),但我很好奇是否有办法做我最初想做的事情?我知道我可以使用foo.GetType().GetMethod("MethodA")
并援引它,但我试图避免反射(reflection)。我主要只是想了解.net中如何动态调用方法。
解决方法:
private delegate void EmptyDelegate();
private void InvokeHelper(EmptyDelegate method)
{
bool retry = false;
do
{
try
{
method.Invoke();
retry = false;
}
catch (MyException ex)
{
retry = HandleException(ex);
}
} while (retry);
}
然后调用:
InvokeHelper(delegate() { foo.MethodA(a, b, c); });
InvokeHelper(delegate() { foo.MethodB(x, y); });
最佳答案
首先,您的签名是
private void InvokeHelper(Delegate method, params object[] args)
但是您犯了一个错误,必须将参数分组到一个数组中才能调用此方法:
InvokeHelper(foo.MethodA, new object[] { a, b, c});
parms
关键字告诉编译器为您执行此操作;你可以这样调用这个方法:
InvokeHelper(foo.MethodA, a, b, c);
其次,如果您的目标是 3.0 或更高版本,请不要使用 Delegate,而使用 Action:
private void InvokeHelper(Action method)
这样调用它:
InvokeHelper(()=> MyMethodToInvoke(a, b, c));
这只是一种总体上更好的方法。
至于为什么会遇到编译器问题,是因为 System.Delegates 讨厌我们。这是一个简单的事实。那是因为没有从方法组到委托(delegate)的隐式转换。
关于c# - 如何在 C# 中动态调用具有任意签名的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/349948/