2010-04-01 2 views
13

Как создать действие в цикле? объяснить (жаль, что это так длинное)Как объединить несколько действий <T> в одном действии <T> в C#?

У меня есть следующие:

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

public class SomeFinder : ISomeInterface 
{ // elided 
} 

и класс, который использует выше:

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

я могу назвать его ни с одним из них, и это работает отлично:

var builder = new Builder(); 

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

Как я могу реализовать вторую реализацию программно? т.е.

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

Я думаю, что я нужен

Expression<Action<ISomeInterface>> x 

или что-то подобное, но для жизни меня, я не вижу, как построить то, что я хочу. Любые мысли были бы очень благодарны!

ответ

22

Это очень легко, потому что делегаты уже многоадресного:

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

Или если у вас есть коллекция из них по какой-то причине:

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

Или даже:

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

Спасибо за быстрый ответ! Я сейчас пробую это, но пока все хорошо. – JohnKeller

+0

Это трюк, спасибо! Отличное напоминание о простых решениях! – JohnKeller

+1

Это так красиво. Я до сих пор не понимал, что такое многоадресные делегаты. –

Смежные вопросы