2010-04-01 7 views
13

¿Cómo construyo una acción Acción en un ciclo? para explicar (lo siento es tan larga)¿Cómo combino varias acciones <T> en una sola acción <T> en C#?

Tengo el siguiente:

public interface ISomeInterface { 
    void MethodOne(); 
    void MethodTwo(string folder); 
} 

public class SomeFinder : ISomeInterface 
{ // elided 
} 

y una clase que utiliza la anterior:

public Map Builder.BuildMap(Action<ISomeInterface> action, 
          string usedByISomeInterfaceMethods) 
{ 
    var finder = new SomeFinder(); 
    action(finder); 
} 

me puede llamar con cualquiera de éstos y funciona genial:

var builder = new Builder(); 

var map = builder.BuildMap(z => z.MethodOne(), "IAnInterfaceName"); 
var map2 = builder(z => 
        { 
        z.MethodOne(); 
        z.MethodTwo("relativeFolderName"); 
        }, "IAnotherInterfaceName"); 

¿Cómo puedo construir la segunda implementación programáticamente? es decir,

List<string> folders = new { "folder1", "folder2", "folder3" }; 
folders.ForEach(folder => 
       { 
       /* do something here to add current folder to an expression 
        so that at the end I end up with a single object that would 
        look like: 
        builder.BuildMap(z => { 
            z.MethodTwo("folder1"); 
            z.MethodTwo("folder2"); 
            z.MethodTwo("folder3"); 
            }, "IYetAnotherInterfaceName"); 
       */ 
       }); 

He estado pensando que necesitan una

Expression<Action<ISomeInterface>> x 

o algo similar, pero para la vida de mí, no estoy viendo cómo construir lo que quiero. ¡Cualquier pensamiento sería muy apreciado!

Respuesta

22

Es muy fácil, ya que los delegados son ya multidifusión:

Action<ISomeInterface> action1 = z => z.MethodOne(); 
Action<ISomeInterface> action2 = z => z.MethodTwo("relativeFolderName"); 
builder.BuildMap(action1 + action2, "IAnotherInterfaceName"); 

O si usted tiene una colección de ellos por alguna razón:

IEnumerable<Action<ISomeInterface>> actions = GetActions(); 
Action<ISomeInterface> action = null; 
foreach (Action<ISomeInterface> singleAction in actions) 
{ 
    action += singleAction; 
} 

O incluso:

IEnumerable<Action<ISomeInterface>> actions = GetActions(); 
Action<ISomeInterface> action = (Action<ISomeInterface>) 
    Delegate.Combine(actions.ToArray()); 
+0

¡Gracias por la respuesta rápida! Estoy probando esto ahora, pero se ve bien hasta ahora. – JohnKeller

+0

¡Eso funcionó, gracias! ¡Un gran recordatorio para pensar primero en las soluciones simples! – JohnKeller

+1

Esto es tan hermoso. Realmente no había entendido para qué eran los delegados de multidifusión hasta ahora. –

Cuestiones relacionadas