Создать делегата с произвольными параметрами - PullRequest
4 голосов
/ 14 ноября 2010

У меня есть System.Reflection.MethodInfo и я хотел бы иметь метод, который создает делегат (предпочтительно Func <...> или Action <...>), который представляет этот метод, учитывая экземпляр для вызова это на.

Так что в идеале я бы хотел что-то вроде следующего псевдо-кода:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
{
    return (TDelegate)((parameters....) => methodToRepresent.Invoke(instanceToInvokeOn, all parameters in an object[]));
}

где TDelegate представляет подпись представленного метода. Если подписи не совпадают, следует выдать исключение.

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

Спасибо

Ответы [ 2 ]

3 голосов
/ 14 ноября 2010

Я не очень понимаю ваш вопрос. Но, возможно, вы хотите это:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
  where TDelegate:class
{
   return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), instanceToInvokeOn, methodToRepresent);
}
2 голосов
/ 14 ноября 2010

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

public delegate void DynamicInvokeDelegate(params object[] args);

public static DynamicInvokeDelegate CreateDynamicInvokeDelegate(MethodInfo method, object instance) {
    return args => method.Invoke(instance, args);
}

Если вам нужен делегат для возврата значения:

public delegate object DynamicInvokeWithReturnDelegate(params object[] args);

public static DynamicInvokeWithReturnDelegate CreateDynamicInvokeWithReturnDelegate(MethodInfo method, object instance) {
    return args => method.Invoke(instance, args);
}

EDIT:

На самом деле, похоже, вам нужен этот код:

public static T GetDelegate<T>(MethodInfo method, object instance)
    where T : class
{
    return (T)(object)Delegate.CreateDelegate(typeof(T), instance, method);
}

Требуется приведение (object), так как компилятор не позволит вам приводить Delegate к какому-либо случайному типу, и вы не можете ограничить T быть делегатом. Приведение через объект удовлетворяет компилятору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...