协慌网

登录 贡献 社区

使用 C#将方法传递为参数

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

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 代码,因为我需要定义参数。

答案

您可以将. net 3.5 中的 Func 委托用作 RunTheMethod 方法中的参数。 Func 委托允许您指定一个方法,该方法采用许多特定类型的参数并返回特定类型的单个参数。这是一个应该起作用的示例:

public class Class1
{
    public int Method1(string input)
    {
        //... do something
        return 0;
    }

    public int Method2(string input)
    {
        //... do something different
        return 1;
    }

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

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

您需要使用一个委托。在这种情况下,您的所有方法都采用string参数并返回一个int最简单地由Func<string, int>委托1 表示。因此,只需进行如下更改即可使您的代码正确无误:

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

从 OP 的示例:

public static int Method1(string mystring)
 {
      return 1;
 }

 public static int Method2(string mystring)
 {
     return 2;
 }

您可以尝试动作代表!然后使用

public bool RunTheMethod(Action myMethodName)
 {
      myMethodName();   // note: the return value got discarded
      return true;
 }

RunTheMethod(() => Method1("MyString1"));

或者

public static object InvokeMethod(Delegate method, params object[] args)
{
     return method.DynamicInvoke(args);
}

然后只需调用方法

Console.WriteLine(InvokeMethod(new Func<string,int>(Method1), "MyString1"));

Console.WriteLine(InvokeMethod(new Func<string, int>(Method2), "MyString2"));