如何在C#中动态调用具有任何签名的方法?
我有一个类,其中包含一些常见的错误处理代码,我想传入要调用的方法和参数,但我不能完全理解语法。我想做的大致如下:如何在C#中动态调用具有任何签名的方法?,c#,C#,我有一个类,其中包含一些常见的错误处理代码,我想传入要调用的方法和参数,但我不能完全理解语法。我想做的大致如下: private void InvokeHelper(Delegate method, params object[] args) { bool retry = false; do { try { method.DynamicInvoke(args); retry = false; } catch (MyExcept
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”)
并调用它,但我试图避免反射。我主要想了解在.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)
但是您犯了一个错误,即必须将arg分组到一个数组中才能调用此方法:
InvokeHelper(foo.MethodA, new object[] { a, b, c});
parms
关键字告诉编译器为您执行此操作;您可以这样调用此方法:
InvokeHelper(foo.MethodA, a, b, c);
其次,如果您的目标是3.0或更高版本,请不要使用委派,而是使用操作:
private void InvokeHelper(Action method)
private void InvokeHelper(Action method)
{
bool retry = false;
do
{
try
{
method();
retry = false;
}
catch (MyException ex)
{
retry = HandleException(ex);
}
} while (retry);
}
public void Test()
{
FooClass foo = new FooClass();
InvokeHelper( () => foo.MethodA(1, "b", 3) );
InvokeHelper( () => foo.MethodB(2, "y"));
}
这样说吧:
InvokeHelper(()=> MyMethodToInvoke(a, b, c));
这是一个更好的方法
至于为什么会出现编译器问题,这是因为System.Delegates讨厌我们。这是一个简单的事实。这是因为没有从方法组到委托的隐式强制转换。这里有一个重写,下面是威尔关于使用操作的建议:
private void InvokeHelper(Action method)
private void InvokeHelper(Action method)
{
bool retry = false;
do
{
try
{
method();
retry = false;
}
catch (MyException ex)
{
retry = HandleException(ex);
}
} while (retry);
}
public void Test()
{
FooClass foo = new FooClass();
InvokeHelper( () => foo.MethodA(1, "b", 3) );
InvokeHelper( () => foo.MethodB(2, "y"));
}
“没有从方法组到委托的隐式转换”。答对 了方法具有显式声明的参数列表。通常,编译器通过检查参数的类型来帮助您确定要使用methodgroup中的哪个重载。在这里,编译器不能这样做。我将其更改为不显式构造对象数组。我不知道为什么我认为我需要这样做——我想是大脑放屁。我花了很长时间才改掉这个习惯。