在c#中使用Functors / Delegates的不同方法

时间:2012-10-30 10:51:58

标签: c# delegates functor

我有一个多次调用的方法,但每次从内部调用具有不同签名的不同方法。

public void MethodOne()
{
//some stuff

*MethodCall();

//some stuff

}

所以MethodOne被多次调用,每次都有不同的*MethodCall()。我想做的是这样的事情:

public void MethodOne(Func<> MethodCall)
{
//some stuff

*MethodCall;

//some stuff

}

但是每个被调用的方法都有不同的返回类型和不同的参数。有没有办法使用Functors做到这一点?如果没有,我将如何做到这一点?

谢谢!

4 个答案:

答案 0 :(得分:1)

您最好的选择是使用非通用Action类型(或MethodInvoker将是相同的),即

public void MethodOne(Action callback)
{
    //some stuff

    if(callback != null) callback();

    //some stuff
}

从这里你可以通过将它包装在调用者处来调用任何方法,即

MethodOne(SimpleMethod); // SimpleMethod has no parameters and returns void
MethodOne(() => MoreComplexMethod(1, "abc")); // this one returns void
MethodOne(() => { MethodThatReturnsSomething(12); }); // anything you like

答案 1 :(得分:1)

你不能在没有提供参数的情况下调用需要参数的函数,所以答案是“不,不可能”

另外,也许你想要以下内容:

void MethodOne(Action a)
{
    // some stuff
    a();
    // some stuff
}

... // somewhere in the code
MethodOne((Action)(() => { DoSomethingOther(1, 2, 3); }));
MethodOne((Action)(() => { DoSomethingEvenDifferent(1, 2, 3, 4, 5); }));

答案 2 :(得分:1)

.Net中的每个代理都是从Delegate派生的类的实例。因此,如果您真的希望将“任意”委托传递给方法,则可以将其作为Delegate传递

要调用它,您需要使用其DynamicInvoke方法。

public void MethodOne(Delegate MethodCall)
{
//some stuff

//Assuming you now have the required parameters
//or add params object[] args to the signature of this method
object res = MethodCall.DynamicInvoke(args); //args is object[] representing the parameters

//some stuff
}

但不建议这样做,因为DynamicInvoke速度很慢,并且它不提供任何编译时安全性。可能你应该重新审视你的设计。

答案 3 :(得分:0)

这基本上是不可能的。您可以为返回类型设置MethodOne泛型,并使用关闭其外部块而不是参数的lambda:

static void Main(string[] args)
{
    int parameterSubst = 1;
    int result = MethodOne<int>(() => parameterSubst);
    string result2 = MethodOne<string>(() =>
    {
        string s = parameterSubst.ToString();
        s += "foo";
        return s;
    });
}

static T MethodOne<T>(Func<T> function)
{
    return function();
}

如您所见,parameterSubst用于传递的Func<T>,但不作为参数。