传递方法作为参数使用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> delegate 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类型。

你也可以尝试Action Delegate!

  public static int Method1(string mystring) { return 1; } public static int Method2(string mystring) { return 2; } public bool RunTheMethod(Action myMethodName) { myMethodName(); 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")); 
 public static T Runner<T>(Func<T> funcToRun) { //Do stuff before running function as normal return funcToRun(); } 

用法:

 var ReturnValue = Runner(() => GetUser(99)); 

你应该使用一个Func<string, int>委托,它代表一个函数把一个string作为参数并返回一个int

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

然后使用它:

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

如果你想在运行时改变调用方法,我会建议使用一个委托: http : //www.codeproject.com/KB/cs/delegates_step1.aspx

它将允许您创建一个对象来存储要调用的方法,并在需要时将其传递给其他方法。

虽然接受的答案是绝对正确的,我想提供一个额外的方法。

我做了一个类似的问题的解决方案后,我在这里结束了。 我正在构建一个插件驱动的框架,作为其中的一部分,我希望人们能够将菜单项添加到应用程序菜单到一个通用列表,而不暴露实际的Menu对象,因为框架可能部署在其他平台上Menu UI对象。 添加关于菜单的一般信息是很容易的,但是允许插件开发者足够的自由来创建菜单被点击时的回调被证明是一个痛苦。 直到我意识到我试图重新发明轮子,正常的菜单调用并触发事件的回调!

所以,一旦你意识到,解决方案就像听起来一样简单,直到现在,我都躲过了。

只需为每个当前方法创建单独的类,如果必须的话,从基类继承,然后向每个方法添加一个事件处理程序。

这是一个没有参数的例子: http : //en.csharp-online.net/CSharp_FAQ : _How_call_a_method_using_a_name_string

与参数: http : //www.daniweb.com/forums/thread98148.html#

你基本上传入一个对象数组和方法的名字。 然后使用Invoke方法。

params对象[]参数

这里是一个例子,它可以帮助你更好地理解如何传递一个函数作为参数。

假设你有页面,你想打开一个子弹出窗口。 在父页面有一个文本框,应该基于子弹出文本框填充。

在这里你需要创建一个委托。

Parent.cs //委托声明public delegate void FillName(String FirstName);

现在创建一个函数来填充你的文本框,函数应该映射代表

 //parameters public void Getname(String ThisName) { txtname.Text=ThisName; } 

现在点击按钮,你需要打开一个Child弹出窗口。

  private void button1_Click(object sender, RoutedEventArgs e) { ChildPopUp p = new ChildPopUp (Getname) //pass function name in its constructor p.Show(); } 

在ChildPopUp构造函数中,您需要创建父//页面的“委托类型”参数

ChildPopUp.cs

  public Parent.FillName obj; public PopUp(Parent.FillName objTMP)//parameter as deligate type { obj = objTMP; InitializeComponent(); } private void OKButton_Click(object sender, RoutedEventArgs e) { obj(txtFirstName.Text); // Getname() function will call automatically here this.DialogResult = true; }