Как объединить несколько действий <T>в одно действие <T>в C #? - PullRequest
16 голосов
/ 01 апреля 2010

Как построить действие Action в цикле? объяснить (извините, это так долго)

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

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 

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

1 Ответ

28 голосов
/ 01 апреля 2010

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

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...