2010-04-01 3 views
13

Comment créer une action Action dans une boucle? pour expliquer (désolé il est si long)comment combiner plusieurs actions <T> en une seule action <T> en C#?

Je donne les résultats suivants:

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

public class SomeFinder : ISomeInterface 
{ // elided 
} 

et une classe qui utilise ce qui précède:

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

je peux l'appeler ou l'autre de ces derniers et il fonctionne great:

var builder = new Builder(); 

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

Comment puis-je générer la deuxième implémentation par programme? à savoir,

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"); 
       */ 
       }); 

J'ai pensé je besoin d'un

Expression<Action<ISomeInterface>> x 

ou quelque chose de similaire, mais pour la vie de moi, je ne vois pas comment construire ce que je veux. Toutes les pensées seraient grandement appréciées!

Répondre

22

Il est vraiment facile, parce que les délégués sont déjà multicast:

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

Ou si vous avez une collection d'entre eux pour une raison quelconque:

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

Ou encore:

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

Merci pour la réponse rapide! J'essaie ça maintenant, mais ça a l'air bien pour le moment. – JohnKeller

+0

Cela a fait l'affaire, merci! Un bon rappel pour penser aux solutions simples d'abord! – JohnKeller

+1

C'est tellement beau. Je n'avais pas vraiment compris à quoi servaient les délégués multicast jusqu'à maintenant. –

Questions connexes