将一个方法作为参数传递

14

我想要能够将一个方法作为参数传递。

例如...

//really dodgy code
public void PassMeAMethod(string text, Method method)
{
  DoSomething(text);
  // call the method
  //method1();
  Foo();
}

public void methodA()
{
  //Do stuff
}


public void methodB()
{
  //Do stuff
}

public void Test()
{
  PassMeAMethod("calling methodA", methodA)
  PassMeAMethod("calling methodB", methodB)
}

我该如何做这件事?


您应该能够使用委托来完成它。 - jimplode
你正在运行哪个版本的.NET框架? - Gavin Miller
3.5,有人可以用上面的例子给我展示一下吗?谢谢。 - raklos
3
这是否回答了你的问题?如何在C#中将方法作为参数传递 - Davide Cannizzo
6个回答

23
你需要使用委托(delegate),它是表示方法的特殊类。你可以定义自己的委托或使用内置的委托之一,但委托的签名必须与你想要传递的方法匹配。
定义自己的委托:
public delegate int MyDelegate(Object a);

这个示例匹配一个返回整数并以对象引用作为参数的方法。

在您的示例中,methodA和methodB都不带参数且返回void,因此我们可以使用内置的Action委托类。

这是修改后的示例:

public void PassMeAMethod(string text, Action method)
{
  DoSomething(text);
  // call the method
  method();    
}

public void methodA()
{
//Do stuff
}


public void methodB()
{
//Do stuff
}

public void Test()
{
//Explicit
PassMeAMethod("calling methodA", new Action(methodA));
//Implicit
PassMeAMethod("calling methodB", methodB);

}

如您所见,您可以明确或隐式地使用委托类型,具体取决于您的需要。


9

使用 Action<T>

示例:

public void CallThis(Action x)
{
    x();
}

CallThis(() => { /* code */ });

6
或 Func<>
Func<int, string> func1 = (x) => string.Format("string = {0}", x);
PassMeAMethod("text", func1);

public void PassMeAMethod(string text, Func<int, string> func1)
{
  Console.WriteLine( func1.Invoke(5) );
}

3

Delegates 是您需要使用的语言特性,以实现您想要做的事情。

以下是使用您上面的代码的示例(使用 Action 委托作为快捷方式):

//really dodgy code
public void PassMeAMethod(string text, Action method)
{
    DoSomething(text);
    method(); // call the method using the delegate
    Foo();
}

public void methodA()
{
    Console.WriteLine("Hello World!");
}    

public void methodB()
{
    Console.WriteLine("42!");
}

public void Test()
{
    PassMeAMethod("calling methodA", methodA)
    PassMeAMethod("calling methodB", methodB)
}

0

c# .net2.0 - 让我展示一个关于将方法作为参数传递的主题的详细答案。在我的场景中,我正在配置一组具有不同_Tick方法的System.Timers.Timer

delegate void MyAction();

// members
Timer tmr1, tmr2, tmr3;
int tmr1_interval = 4.2, 
    tmr2_interval = 3.5;
    tmr3_interval = 1;


// ctor
public MyClass()
{
  ..
  ConfigTimer(tmr1, tmr1_interval, this.Tmr_Tick);
  ConfigTimer(tmr2, tmr2_interval, (sndr,ev) => { SecondTimer_Tick(sndr,ev); }); 
  ConfigTimer(tmr3, tmr3_interval, new MyAction((sndr,ev) => { Tmr_Tick((sndr,ev); }));
  ..
}

private void ConfigTimer(Timer _tmr, int _interval, MyAction mymethod)
{
  _tmr = new Timer() { Interval =  _interval * 1000 };
  // lambda to 'ElapsedEventHandler' Tick
  _tmr.Elpased += (sndr, ev) => { mymethod(sndr, ev); };
  _tmr.Start();
}

private void Tmr_Tick(object sender, ElapsedEventArgs e)
{
  // cast the sender timer
  ((Timer)sender).Stop();
  /* do your stuff here */
  ((Timer)sender).Start();
}

// Another tick method
private void SecondTimer_Tick(object sender, ElapsedEventArgs e) {..}

0
在BrunoLM的基础上进行扩展,因为那个例子很简短。
//really dodgy code
public void PassMeAMethod(string text, Action method)
{
  DoSomething(text);
  method();
  Foo();
}

// Elsewhere...

public static void Main(string[] args)
{
    PassMeAMethod("foo", () =>
        {
            // Method definition here.
        }
    );

    // Or, if you have an existing method in your class, I believe this will work
    PassMeAMethod("bar", this.SomeMethodWithNoParams);
}

你能在静态 void 中使用 this 吗? - feedc0de

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接