2010-10-25 6 views
9

Я хочу иметь возможность передать метод в качестве параметра.Передайте метод как параметр

например ..

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

Как я могу это сделать?

+0

Вы должны иметь возможность сделать это с делегатами. – jimplode

+0

Какую версию .NET Framework вы используете? –

+0

3.5, может кто-нибудь показать мне, используя пример выше? спасибо – raklos

ответ

19

Вам необходимо использовать делегат, который представляет собой специальный класс, представляющий метод. Вы можете либо определить свой собственный делегат, либо использовать один из встроенных, но подпись делегата должна соответствовать методу, который вы хотите передать.

Определение собственных:

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

} 

Как вы можете видеть, вы можете либо использовать тип делегата, явно или неявно, в зависимости от того подходит вам.

7

Использование Action<T>

Пример:

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

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

Или 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)); 
} 
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); 
} 
+0

Можете ли вы использовать 'this' в статическом пустоте? –

2

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 - Позвольте мне показать подробный ответ на тему (пройти-а-метод-как-параметра). В моем сценарии я настраиваю набор 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) {..} 
Смежные вопросы