Как работают анонимные делегаты в ControllerActionInvoker.InvokeActionMethodWithFilters

1

Я пытаюсь сделать переход от PHP к ASP.NET, и при этом я пытаюсь узнать, как работает MVC, однако я застрял с ControllerActionInvoker.InvokeActionMethodWithFilters, поскольку я не понимаю, что происходит.

Фрагмент, с которым я борюсь, следующий:

protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
    ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));
    return thunk();
}

Полный исходный код можно найти по следующему URL-адресу: https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ControllerActionInvoker.cs#L371

В частности, я не уверен, что делает следующее:

    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

Поскольку я никогда не видел строку, содержащую следующее: continue =() =>

Я также не могу найти ответ на Google, потому что он не признает =() => в качестве условия поиска.

Я так же путаюсь со следующим фрагментом кода, который имеет похожий синтаксис:

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));

Исходя из фона PHP, я раньше этого синтаксиса не видел, и ресурсы, которые я читал в Интернете, на самом деле тоже не очень понятны для меня.

На основе следующего SO-вопроса: делегирование ключевого слова против лямбда-нотации

Если бы мне пришлось переписать следующее...

    Func<ActionExecutedContext> continuation = () =>
                                               new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

Было бы так...

    Func<ActionExecutedContext> continuation = delegate(new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */))
                                               {
                                                   Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
                                               };

И то же самое для второго фрагмента...

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
                                                                    (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));

Который, если я не ошибаюсь, был бы...

    // need to reverse the filter list because the continuations are built up backward
    Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation, delegate(next, filter) {InvokeActionMethodFilter(filter, preContext, next)});

Или я все еще не понимаю?

  • 3
    Если вы спрашиваете, что означает синтаксис = () => , это назначение анонимного делегата.
Теги:

1 ответ

0
Лучший ответ

Это лямбда-выражения, и в этом конкретном случае это не более чем анонимные функции.

Который, если я не ошибаюсь, был бы...

Неправильно. Делегат должен работать с двумя параметрами next и filter, который возвращает делегат другой функции, InvokeActionMethodFilter метод InvokeActionMethodFilter:

Func<ActionExecutedContext> thunk =
    filters.Reverse()
           .Aggregate(continuation,
                      delegate(Func<ActionExecutedContext> next, IActionFilter filter)
                      {
                          return delegate
                          {
                              return InvokeActionMethodFilter(filter, preContext, next);
                          };
                      });

Этот код вызывает вызов IActionFilters, пока некоторые из них не приведут к результату. И в конце цепи - ваш метод действий. next переменная - либо функция выполнения фильтра () => InvokeActionMethodFilter(filter, preContext, next), либо continuation в конце цепочки. Для InvokeActionMethodFilter дополнительной информации см. Реализацию InvokeActionMethodFilter.

  • 0
    Спасибо за вашу помощь в том, что вы сказали, я должен быть в состоянии изучить это дальше. Очень признателен.
  • 0
    Кроме того, чтобы помочь другим, пришедшим из PHP-фона, поскольку я немного ошибся из-за происходящего, ниже приведен хороший ресурс по созданию объектов с использованием инициализатора объектов: msdn.microsoft.com/en-us/library/bb397680.aspx

Ещё вопросы

Сообщество Overcoder
Наверх
Меню