我有几个方法都具有相同的参数类型和返回值,但名称和块不同。我想将要运行的方法的名称传递给另一个将调用传递的方法的方法。

public int Method1(string)
{
    // Do something
    return myInt;
}

public int Method2(string)
{
    // Do something different
    return myInt;
}

public bool RunTheMethod([Method Name passed in here] myMethodName)
{
    // Do stuff
    int i = myMethodName("My String");
    // Do more stuff
    return true;
}

public bool Test()
{
    return RunTheMethod(Method1);
}

这段代码不起作用,但这是我正在尝试做的。我不明白的是如何编写RunTheMethod代码,因为我需要定义参数。


当前回答

如果传递的方法需要接受一个参数并返回一个值,那么Func是最好的方法。这里有一个例子。

public int Method1(string)
{
    // Do something
    return 6;
}

public int Method2(string)
{
    // Do something different
    return 5;
}

public bool RunTheMethod(Func<string, int> myMethodName)
{
    // Do stuff
    int i = myMethodName("My String");
    Console.WriteLine(i); // This is just in place of the "Do more stuff"
    return true;
}

public bool Test()
{
    return RunTheMethod(Method1);
}

阅读此处的文档

但是,如果作为参数传递的方法没有返回任何内容,也可以使用Action。对于传递的方法,它最多支持16个参数。这里有一个例子。

public int MethodToBeCalled(string name, int age)
{
    Console.WriteLine(name + "'s age is" + age);
}

public bool RunTheMethod(Action<string, int> myMethodName)
{
    // Do stuff
    myMethodName("bob", 32); // Expected output: "bob's age is 32"
    return true;
}

public bool Test()
{
    return RunTheMethod(MethodToBeCalled);
}

阅读此处的文档

其他回答

您需要使用代理。在这种情况下,所有方法都接受一个字符串参数并返回一个int-这最简单地由Func<string,int>delegate1表示。因此,您的代码可以通过以下简单的更改变得正确:

public bool RunTheMethod(Func<string, int> myMethodName)
{
    // ... do stuff
    int i = myMethodName("My String");
    // ... do more stuff
    return true;
}

诚然,代表们拥有比这多得多的权力。例如,使用C#,您可以从lambda表达式创建一个委托,因此您可以这样调用方法:

RunTheMethod(x => x.Length);

这将创建如下匿名函数:

// The <> in the name make it "unspeakable" - you can't refer to this method directly
// in your own code.
private static int <>_HiddenMethod_<>(string x)
{
    return x.Length;
}

然后将该委托传递给RunTheMethod方法。

您可以将委托用于事件订阅、异步执行、回调-所有类型的事情。它非常值得一读,特别是如果你想使用LINQ。我有一篇文章,主要是关于代表和事件之间的差异,但无论如何你可能会发现它很有用。


1这只是基于框架中的泛型Func<T,TResult>委托类型;您可以很容易地声明自己的:

public delegate int MyDelegateType(string value)

然后将参数设置为MyDelegateType类型。

我不知道谁可能需要这个,但如果您不确定如何使用委托发送lambda,当使用委托的函数不需要在其中插入任何参数时,您只需要返回值。

因此,您也可以这样做:

public int DoStuff(string stuff)
{
    Console.WriteLine(stuff);
}

public static bool MethodWithDelegate(Func<int> delegate)
{
    ///do stuff
    int i = delegate();
    return i!=0;
}

public static void Main(String[] args)
{
    var answer = MethodWithDelegate(()=> DoStuff("On This random string that the MethodWithDelegate doesn't know about."));
}

如果传递的方法需要接受一个参数并返回一个值,那么Func是最好的方法。这里有一个例子。

public int Method1(string)
{
    // Do something
    return 6;
}

public int Method2(string)
{
    // Do something different
    return 5;
}

public bool RunTheMethod(Func<string, int> myMethodName)
{
    // Do stuff
    int i = myMethodName("My String");
    Console.WriteLine(i); // This is just in place of the "Do more stuff"
    return true;
}

public bool Test()
{
    return RunTheMethod(Method1);
}

阅读此处的文档

但是,如果作为参数传递的方法没有返回任何内容,也可以使用Action。对于传递的方法,它最多支持16个参数。这里有一个例子。

public int MethodToBeCalled(string name, int age)
{
    Console.WriteLine(name + "'s age is" + age);
}

public bool RunTheMethod(Action<string, int> myMethodName)
{
    // Do stuff
    myMethodName("bob", 32); // Expected output: "bob's age is 32"
    return true;
}

public bool Test()
{
    return RunTheMethod(MethodToBeCalled);
}

阅读此处的文档

如果要将Method作为参数传递,请使用:

using System;

public void Method1()
{
    CallingMethod(CalledMethod);
}

public void CallingMethod(Action method)
{
    method();   // This will call the method that has been passed as parameter
}

public void CalledMethod()
{
    Console.WriteLine("This method is called by passing it as a parameter");
}

您应该使用一个Func<string,int>委托,它表示一个接受字符串参数并返回int值的函数:

public bool RunTheMethod(Func<string, int> myMethod)
{
    // Do stuff
    myMethod.Invoke("My String");
    // Do stuff
    return true;
}

然后以这种方式调用它:

public bool Test()
{
    return RunTheMethod(Method1);
}