【问题标题】:Pass a method as a parameter [duplicate]将方法作为参数传递[重复]
【发布时间】:2011-04-30 06:00:08
【问题描述】:

我希望能够将方法作为参数传递。

例如..

//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)
}

我该怎么做?

【问题讨论】:

  • 你应该可以和代表一起做。
  • 您运行的是哪个版本的 .NET 框架?
  • 3.5,有人可以用上面的例子告诉我吗?谢谢
  • 这能回答你的问题吗? Pass Method as Parameter using C#

标签: c# .net-3.5


【解决方案1】:

您需要使用委托,它是代表方法的特殊类。您可以定义自己的委托或使用内置委托之一,但委托的签名必须与您要传递的方法相匹配。

定义你自己的:

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);

}

如您所见,您可以显式或隐式使用委托类型,以适合您的方式。

【讨论】:

    【解决方案2】:

    使用Action<T>

    例子:

    public void CallThis(Action x)
    {
        x();
    }
    
    CallThis(() => { /* code */ });
    

    【讨论】:

      【解决方案3】:

      或函数

      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) );
      }
      

      【讨论】:

        【解决方案4】:

        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)
        }
        

        【讨论】:

          【解决方案5】:

          以 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);
          }
          

          【讨论】:

          • 你能在静态空白中使用this吗?
          【解决方案6】:

          c# .net2.0 - 让我为这个主题提供一个详细的答案(pass-a-method-as-a-parameter)。 在我的场景中,我正在配置一组 System.Timers.Timer-s,每个都有不同的 _Tick 方法。

          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) {..}
          

          【讨论】:

            猜你喜欢
            • 2014-04-22
            • 2013-09-13
            • 1970-01-01
            • 2013-07-01
            • 2015-03-04
            • 2011-07-21
            • 2010-11-16
            • 2013-01-03
            相关资源
            最近更新 更多