2010-10-25 14 views
9

Chcę móc przekazać metodę jako parametr.Przekaż metodę jako parametr

np ..

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

Jak mogę to zrobić?

+0

Powinieneś być w stanie to zrobić z delegatami. – jimplode

+0

Która wersja architektury .NET działa? –

+0

3.5, czy ktoś może pokazać mi, używając powyższego przykładu? dzięki – raklos

Odpowiedz

19

Musisz użyć delegata, który jest specjalną klasą reprezentującą metodę. Możesz zdefiniować własnego delegata lub użyć jednego z wbudowanych, ale podpis delegata musi być zgodny z metodą, którą chcesz przekazać.

Definiowanie własnego:

public delegate int MyDelegate(Object a); 

Przykład ten pasuje do metody, która zwraca liczbę całkowitą i zaczyna odniesienie do obiektu jako parametr.

W twoim przykładzie zarówno metodaA, jak i metodaB nie przyjmują żadnych parametrów, które zwróciłyby pustkę, więc możemy użyć wbudowanej klasy delegatów akcji.

tutaj jest przykład modyfikowany:

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

} 

Jak widać, można użyć typu delegata bezpośrednio lub pośrednio, w zależności co Ci odpowiada.

7

Zastosowanie Action<T>

Przykład:

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

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

Albo 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

Opierając się na co BrunoLM zrobił, jako że przykładem była krótka.

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

Czy możesz użyć "tego" w statycznej próżni? –

2

Delegates to funkcja językowa, której należy użyć do wykonania tego, co chcesz zrobić.

Oto przykład przy użyciu kodu masz powyżej (przy użyciu delegata Action jako skrótu):

//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 - Pokażę szczegółowe odpowiedzi na ten temat (pass-a-method-as-a-parameter). W moim scenariuszu konfiguruję zestaw System.Timers.Timer -s, każdy z inną metodą: _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) {..} 
Powiązane problemy