Получите имя метода Используя лямбда-выражение

Я пытаюсь получить название метода на типе с помощью лямбда-выражения. Я использую Windows Identity Foundation и потребность определить политики доступа с именем типа с пространством имен как ресурс и имя метода как действие. Вот пример.

Это - тип, от которого я получил бы имя типа и имя метода:

namespace My.OrderEntry {
    public class Order {
        public void AddItem(string itemNumber, int quantity) {}
    }
}

Это - то, как я хотел бы определить политику доступа через DSL:

ForResource<Order>().Performing(o => o.AddItem).AllowUsersHaving(new Claim());

От того оператора я хотел бы получить "Мой. OrderEntry. Порядок" как ресурс и "AddItem" как действие. Получение имени типа с пространством имен не является никакой проблемой, но я не думаю, что могу использовать лямбду для метода как, я пытаюсь сделать.

public static IPermissionExp Performing<T>(
    this IActionExp<T> exp,
    Func<T, delegate???> action) {} //this is where I don't know what to define

Этот вид вещи даже возможно сделать? Там другой путь состоит в том, чтобы сделать этот вид вещи, не используя волшебные строки?

17
задан FrustratedWithFormsDesigner 22 February 2010 в 21:27
поделиться

4 ответа

Это можно сделать двумя способами:

1: вы можете создавать перегрузки, которые принимают различные делегаты Func и Action (например, Expression > . Обратите внимание, что вызывающим абонентам потребуется явно указать общие параметры либо в вызове метода, либо путем создания делегата. Это будет использоваться следующим образом:

ForResource<Order>().Performing(o => new Action<string>(o.AddItem)).AllowUsersHaving(new Claim());

2: Вы можете взять Expression , которое содержит вызов метода, и проанализировать вызываемую MethodInfo из дерева выражений. Это будет использоваться следующим образом:

ForResource<Order>().Performing(o => { o.AddItem(null); }).AllowUsersHaving(new Claim());
7
ответ дан 30 November 2019 в 14:33
поделиться

Недавно я сделал кое-что на работе, где вы определили метод, используя лямбда, имя которой затем принял внутренний объект. Вы также можете использовать строки или передать MethodInfo, но первый тип не является безопасным по типу (и опечатки представляют большой риск), а последний не очень элегантен.

В основном у меня был такой метод (это не точный метод, он немного более продвинутый):

public void SetRequest(Request req, Expression<Func<Service, Func<long, IEnumerable<Stuff>>> methodSelector);

Ключевым моментом здесь является «Выражение», оно позволяет вам «выбрать» такой метод:

SetRequest(req, service => service.SomeMethodTakingLongReturningStuffs);

Селектор метода представляет собой дерево выражений, из которого затем можно извлекать различные биты данных. Я не помню точно, как выглядит получившееся дерево, это также зависит от того, как выглядят ваши лямбды.

1
ответ дан 30 November 2019 в 14:33
поделиться

Вместо этого вы можете передать его как действие, которое не приводит к принудительному возвращению типа. Однако это все еще немного запутано, потому что вам нужно передать некоторые аргументы методу, чтобы он скомпилировался.

0
ответ дан 30 November 2019 в 14:33
поделиться

Похоже, это то, что вам нужно, если вы хотите, чтобы имя метода делегата действия передавалось в функцию Performing.

public static IPermissionExp Performing<T>( 
    this IActionExp<T> exp, 
    Expression<Action<T, string, int>> action) 
{
    var expression = action.Body as MethodCallExpression;
    string actionMethodName = string.Empty;
    if (expression != null)
    {
        actionMethodName = expression.Method.Name;
    }
    // use actionMethodName ("AddItem" in the case below) here
}

Это позволит вам вызывать метод следующим образом...

ForResource<Order>().Performing((o, a, b) => o.AddItem(a, b)).AllowUsersHaving(new Claim()); 
3
ответ дан 30 November 2019 в 14:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: