2010-10-25 31 views
9

Desidero poter passare un metodo come parametro.Passare un metodo come parametro

ad es ..

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

Come posso fare questo?

+0

Dovresti riuscire a farlo con i delegati. – jimplode

+0

Quale versione del framework .NET è in esecuzione? –

+0

3.5, qualcuno può mostrarmi usando l'esempio sopra? grazie – raklos

risposta

19

È necessario utilizzare un delegato, che è una classe speciale che rappresenta un metodo. È possibile definire il proprio delegato o utilizzare uno di quelli incorporati, ma la firma del delegato deve corrispondere al metodo che si desidera passare.

Definizione del:

public delegate int MyDelegate(Object a); 

Questo esempio corrisponde a un metodo che restituisce un intero e prende un riferimento a un oggetto come parametro.

Nell'esempio, sia methodA che methodB non accettano parametri restituiscono void, quindi è possibile utilizzare la classe del delegato Action incorporata.

Qui è la vostra esempio modificato:

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

} 

Come si può vedere, è possibile utilizzare il tipo di delegato esplicitamente o implicitamente, a seconda di quale vi si addice.

7

Usa Action<T>

Esempio:

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

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

O Funz <>

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

Costruire su ciò che ha fatto BrunoLM, come quella ad esempio è stata breve.

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

Puoi usare 'this' in un vuoto statico? –

2

Delegates sono le funzionalità del linguaggio che è necessario utilizzare per realizzare ciò che si sta tentando di fare.

Ecco un esempio utilizzando il codice si dispone sopra (utilizzando il Action delegato come scorciatoia):

//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 - mi permetta di mostrare una risposta dettagliata per l'argomento (pass-un-procedimento-as-a-parametro). Nel mio scenario sto configurando un set di System.Timers.Timer -s, ognuno con un diverso metodo _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) {..} 
Problemi correlati