выполнить действие A для каждого B в каждом C ... если D в дереве - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь создать абстрактный класс, который выполняет заданные задачи для определенных c элементов. Два примера с общим logi c:

Пример A

foreach (DraftDocument draft in drafts)
    foreach (Sheet sheet in draft.Sheets)
        foreach (Symbol symbol in sheet.Symbols)
            if(conditions) do action

Пример B

foreach (DraftDocument draft in drafts)
    foreach (Sheet sheet in draft.Sheets)
        foreach (View view in sheet.Views)
            if(conditions) do action

I хотел бы повторно использовать foreach logi c и создать функцию, которая принимает как метод условия, так и метод действия, и выполняет ее для заданного набора данных (в данном случае списка DraftDocuments).

Как бы лучше всего их создать? Я что-то читал о делегате Fun c, но не уверен, как это правильно реализовать.

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

Создание метода расширения для инкапсуляции предиката и логики действий c и использование SelectMany, IMHO, достаточно:

public static void DoActionIf<TSource>(
    this IEnumerable<TSource> source,
    Predicate<TSource> predicate,
    Action<TSource> action)
{
    foreach (var s in source)
    {
        if (predicate(s))
            action(s);
    }
}

И вы бы использовали его как:

drafts.SelectMany(draft => draft.Sheets)
      .SelectMany(sheet => sheet.Symbols)
      .DoActionIf(symbol => symbol != null, 
                  symbol => Console.WriteLine(sy));
0 голосов
/ 06 августа 2020

Вы можете сделать что-то вроде

public class DocumentVisitor
{
   private readonly IEnumerable<DraftDocument> _drafts;

   private void Visit(Action<Sheet> visitor)
   {
       foreach(DraftDocument draft in _drafts)
           foreach(Sheet sheet in draft.Sheets)
               visitor(sheet);
   }

   public DocumentVisitor(IEnumerable<DraftDocument> drafts) => _drafts = drafts;

   public void VisitSymbols(Action<Symbol> visitor) =>
       Visit(sheet =>
       {
           foreach(Symbol symbol in sheet.Symbols)
               visitor(symbol);
       });

   public void VisitViews(Action<View> visitor) =>
       Visit(sheet=>
       {
           foreach(View view in sheet.Views)
               visitor(view);
       });

}

...