Преобразовать B(C(),D()) в (c,d)=›B(()=›c(),()=›d()) — Создание оболочек делегатов из MethodInfos?

В конечном счете, я с нетерпением жду подхода, основанного на отражении, для создания оболочки делегата для метода B(C(),D()) - для чего-то вроде (c,d)=>B(()=>c( ),()=>d())

Первый вопрос. Учитывая, что у вас есть Methodinfo, каковы соображения по созданию типа делегата (посредством отражения), который соответствует этой сигнатуре метода?

У вас есть ссылка на кусок кода любого проекта с открытым исходным кодом, который делает это? :П

Обновление: вот общий способ создания делегата для methodinfo Build делегатом от MethodInfo? - Я думаю, что рекурсивную обертку части параметров я должен отработать на выходных.


person amazedsaint    schedule 27.10.2010    source источник
comment
Рад, что вы этого ждете. Приятно провести время. ;)   -  person Guffa    schedule 27.10.2010
comment
Просто слоняюсь и ищу Джонскита :P   -  person amazedsaint    schedule 27.10.2010
comment
Почему вы хотите предоставить еще один слой ненужной косвенности?   -  person leppie    schedule 27.10.2010
comment
Похоже, вы пытаетесь сделать то, что сейчас объясняет Эрик в своем блоге.   -  person Oliver    schedule 27.10.2010
comment
@leppie Почему ты думаешь, что в этом нет необходимости? Должно быть полезно для создания оберток для каррирования, стиля непрерывной передачи и т. д.   -  person amazedsaint    schedule 27.10.2010
comment
@Oliver, вот и вы, динамическая оболочка для CPS поверх существующих методов, конечно, вдохновленная этим blogs.msdn.com/b/ericlippert/archive/2010/10/21/   -  person amazedsaint    schedule 27.10.2010
comment
@leppie скучающие умные люди опасны.   -  person Winston Smith    schedule 27.10.2010
comment
@amazedsaint: CPS - это стиль прохождения продолжения. Ваш код не фиксирует продолжение, поэтому я не вижу, что здесь пытаются сделать.   -  person leppie    schedule 27.10.2010
comment
@amazedsaint: Кроме того, если вы не используете хвостовые вызовы, CPS взорвет ваш стек. @Eric Lippert не упоминает этот очень важный момент.   -  person leppie    schedule 27.10.2010
comment
Извините, я сделал классическую ошибку, я имел в виду proper tail recursion, а не tail calls (последнее является деталью реализации).   -  person leppie    schedule 27.10.2010
comment
@leppie Мой первоначальный вопрос был просто направлен на создание оболочки делегата из информации о методе, CPS нигде в вопросе не было. Упомянул CPS и каррирование, чтобы уточнить, почему перенаправление полезно, а не строго по исходному вопросу. Спасибо   -  person amazedsaint    schedule 27.10.2010


Ответы (2)


Используйте Expression для создания динамических методов. Вот пример по вашему вопросу. Я беру Console.Write(string s) в качестве примера.

    MethodInfo method = typeof(Console).GetMethod("Write", new Type[] { typeof(string) });
    ParameterExpression parameter = Expression.Parameter(typeof(string),"str");
    MethodCallExpression methodExp = Expression.Call(method,parameter);
    LambdaExpression callExp = Expression.Lambda(methodExp, parameter);
    callExp.Compile().DynamicInvoke("hello world");
person Cheng Chen    schedule 27.10.2010
comment
Неа. Лучший общий подход здесь stackoverflow.com/questions/ 1124563/ - но это не переносит параметры. - person amazedsaint; 27.10.2010

Мне удалось создать рабочий делегат из MethodInfo такого метода:

Метод и делегат:

public static int B(Func<int> c, Func<int> d) {
  return c() + d();
}

public delegate int TwoFunc(Func<int> c, Func<int> d);

Код:

MethodInfo m = typeof(Program).GetMethod("B");
TwoFunc d = Delegate.CreateDelegate(typeof(TwoFunc), m) as TwoFunc;
int x = d(() => 1, () => 2);
Console.WriteLine(x);

Выход:

3

Хотя не уверен, что это полезно...

person Guffa    schedule 27.10.2010