C # Получить реализацию делегата (Func) из конкретного класса через отражение? - PullRequest
1 голос
/ 02 июня 2009

Извините за плохое объяснение проблемы

полностью переписывающий вопрос

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

public TReturn FindCached<TSearch, TReturn>(Func<TSearch, TReturn> searchMethod) 
            where TSearch : ISearchSpecification
            where TReturn : class
        {
            SearchSpecification spec = new GetConcreteSearchSpecification<TSearch>();

            //insert magic here to get an attribute from the method on 
            //the spec class that searchMethod invokes on the line below

            return searchMethod(spec);
        }

Итак, у меня есть делегат (searchMethod) и объект (spec), для которого я хочу вызвать делегата. Я хочу проверить объект (spec), чтобы найти пользовательский атрибут в методе , который searchMethod будет вызывать при вызове.

Надеюсь, это понятнее.

Спасибо

Ответы [ 3 ]

1 голос
/ 02 июня 2009

Предполагая, что вы имели в виду searchMethod как переменную типа Func<TSearch, TReturn> и mySearchSpec как некоторую реализацию ISearchSpecification<TSearch>, вы в основном спрашиваете, как получить атрибуты для класса.

Для этого используйте что-то вроде:

object[] attrs = typeof(mySearchSpec).GetCustomAttributes(false);

Предполагая, что тип mySearchSpec является открытым, в противном случае вам может потребоваться другая перегрузка для GetCustomAttributes

Добавление
На основании вашего пересмотренного вопроса, чтобы получить атрибуты метода для фактического типа spec используется:

Type t = spec.GetType();
MethodInfo m = t.GetMethod("nameOfMethodToBeCalledHere");
object[] attrs = m.GetCustomAttributes(false);

Опять же, обратите внимание, что вам могут потребоваться перегрузки для GetMethod или GetCustomAttributes в зависимости от реализации фактического класса.

Примечание:
Однако кажется, что вы, возможно, спрашиваете о методе, вызываемом в return searchMethod(spec);, но это searchMethod, а не какой-то метод в spec вообще.

Если вы хотите атрибуты на searchMethod (ничего общего с spec):

MethodInfo m = searchMethod.Method;
object[] attrs = m.GetCustomAttributes(false);

Я думаю, что теперь охватывает все перестановки смысла ...

0 голосов
/ 04 июня 2010

Я столкнулся с подобной ситуацией, ответ Джеррейвла объяснил именно то, что я хотел.

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

МетодInfo был ключом.

Где у меня есть такой метод:

public static bool TimeMethod(Func<bool> someMethod)

А потом я хочу динамически получить его имя или некоторые атрибуты.

MethodInfo m = someMethod.Method;
object[] attrs = m.GetCustomAttributes(typeof(MonitoringDescriptionAttribute), true);
string name = m.Name;

Приветствия

0 голосов
/ 08 июля 2009

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

  • У вас есть лямбда-функция (которую вы описываете как делегат) с именем searchMethod.
  • У вас есть объект, сгенерированный по фабричному шаблону и называемый spec

Итак, у вас есть метод где-то вроде этого:

[MyCustomAttribute]
public RetClass MyMethod( SearchSpecification input ) {
    return input.GetRetClass();
}

И вы вызываете этот метод с помощью:

var result = FindCached( MyMethod );

А в FindCached вы хотите найти MyCustomAttribute - в этом случае ответ @ jerryjvl правильный.

Ваша проблема в том, что вы также можете сделать:

var result = FindCached( x => x.GetRetClass() );

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

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

var result = FindCached( "GetRetClass" );
...