2010-10-25 23 views
9

Quiero poder pasar un método como parámetro.Pase un método como parámetro

por ejemplo ..

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

¿Cómo puedo hacer esto?

+0

Debería poder hacerlo con los delegados. – jimplode

+0

¿Qué versión de .NET Framework está ejecutando? –

+0

3.5, ¿alguien me puede mostrar usando el ejemplo anterior? gracias – raklos

Respuesta

19

Necesita usar un delegado, que es una clase especial que representa un método. Puede definir su propio delegado o usar uno de los integrados, pero la firma del delegado debe coincidir con el método que desea aprobar.

Definir su propio:

public delegate int MyDelegate(Object a); 

Este ejemplo partidos un método que devuelve un entero y toma una referencia de objeto como un parámetro.

En su ejemplo, tanto el método A como el método B no toman ningún parámetro que haya devuelto el vacío, entonces podemos usar la clase de delegado Acción incorporada.

Aquí está su ejemplo modificado:

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

} 

Como se puede ver, se puede utilizar el tipo de delegado, explícita o implícitamente, el que más le convenga.

7

Uso Action<T>

Ejemplo:

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

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

O 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

Sobre la base de lo que hizo BrunoLM, como ese ejemplo fue 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

¿Se puede usar 'this' en un vacío estático? –

2

Delegates son la función de idioma que tendrá que usar para lograr lo que está tratando de hacer.

Aquí hay un ejemplo usando el código que tiene más arriba (usando el delegado Action como un acceso directo):

//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 - Te voy a enseñar una respuesta detallada para el tema (pass-a-method-as-a-parameter). En mi escenario, estoy configurando un conjunto de System.Timers.Timer -s, cada uno con un método diferente _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) {..} 
Cuestiones relacionadas