Понимание списка делегата функции (лямбда-выражения)

#c#

#c#

Вопрос:

Я начал использовать лямбда-выражение и теперь часто использую его, но только простые :-). Иногда я действительно путаюсь в понимании лямбда-выражений в нашей существующей базе кода. Изо всех сил пытался понять приведенный ниже код, но все еще не смог полностью расшифровать:-(. Я думаю, что из-за использования делегата функции я не могу понять. Я знаю, что делегат функций используется, когда делегат возвращает что-то. Но в данном случае нет подсказки.

Фрагмент кода:

  public class PrintProvider
 {
     private readonly IInstructionSheetViews _instructionSheetViews;
     public PrintProvider(IInstructionSheetViews instructionSheetViews)
     {
         _instructionSheetViews = instructionSheetViews;
     }
     public void AddReport()
     {
  // Some implementation code goes here
         var printViews = _instructionSheetViews.PrintViews;
  // Some implementation code goes here
     }
 }

public class InstructionSheetViews : IInstructionSheetViews
 {
     private readonly IInstructionSheetFactory _factory;
     private IEnumerable<IReport> _instructionSheetView;
     private List<Func<IInstructionSheetFactory, IReport>> _instructionSheetViewList;

    public InstructionSheetViews(IInstructionSheetFactory factory)
     {
         _factory = factory;
     }

    public IEnumerable<IReport> PrintViews
     {
         get
         {
             if (_instructionSheetView == null)
             {
                 Init();
                 _instructionSheetView = _instructionSheetViewList.Select(x => x(_factory));
             }

            return _instructionSheetView;
         }
     }

    private void Init()
     {
          _instructionSheetViewList = new List<Func<IInstructionSheetFactory, IReport>>();
         _instructionSheetViewList.Add(x => x.BuildCommonData());
         _instructionSheetViewList.Add(x => x.BuildSpecificData());
     }
 }
  

В приведенном выше фрагменте кода метод AddReport вызывает «_instructionSheetViews .PrintViews» и этот метод в свою очередь вызывает «Init ()».

Q1. Что именно добавляется в «_instructionSheetViewList» здесь —

     _instructionSheetViewList.Add(x => x.BuildCommonData());. 
  

Я могу догадаться, что он добавляет метод, который возвращает «iReport». Но «_instructionSheetViewList» содержит список «Функций». Итак, в идеале не должно ли оно содержать метод, который принимает входные данные как «IInstructionSheetFactory» и возвращает «iReport»?

Вопрос 2. Как работает это утверждение. В основном поток управления.

 _instructionSheetViewList.Select(x => x(_factory));
  

Может кто-нибудь, пожалуйста, объяснить мне?

Заранее спасибо.

Комментарии:

1. Q1: добавляет делегат функций к отложенному вызову метода. Q2: вызывает отложенный метод. Вот и все.

2. «разве он не должен содержать метод, который принимает входные данные как «IInstructionSheetFactory» и возвращает «iReport»?» — да, и это именно то, что x => x.BuildCommonData() есть. Итак, в чем ваш вопрос? «Может кто-нибудь, пожалуйста, объясните мне?» — что вы не понимаете? Вы читали документацию по Select() методу? Вы читали документацию о делегатах и о том, как они вызываются? Ваши вопросы слишком расплывчаты, чтобы понять, какой ответ вам здесь нужен… SO не является идеальным форумом для объяснения широких концепций в первую очередь, но если вам нужна помощь, вам нужно быть более конкретным .

Ответ №1:

Итак, в идеале не должно ли оно содержать метод, который принимает входные данные как «IInstructionSheetFactory» и возвращает «iReport»?

Это так. _instructionSheetViewList.Add(x => x.BuildCommonData()); в основном эквивалентно этому:

  _instructionSheetViewList.Add(anonymousMethod12345);
/*...*/
public static IReport anonymousMethod12345 (IInstructionSheetFactory x)
{
    return x.BuildCommonData();
}
  

Ответ №2:

  _instructionSheetViewList.Add(x => x.BuildCommonData());
  

эквивалентно —

 private IReport GetReport(IInstructionSheetFactory x)
    {
        return x.BuildCommonData();
    }
  

И когда вы это сделаете —

 _instructionSheetViewList.Select(x => x(_factory)); 
  

на самом деле он вызывает метод с Func в качестве входного параметра для того метода
, который в свою очередь вызывает метод, на который ссылается делегат функции с _factory в качестве входного параметра

 private IReport DoSomething(Func<IInstructionSheetFactory, IReport> x)
    {
        return x(_factory);
    }
  

Надеюсь, это поможет.