Генерация типов делегатов динамически в C # - PullRequest
5 голосов
/ 21 апреля 2009

У нас есть требование, когда нам нужно генерировать типы делегатов на лету. Нам нужно сгенерировать делегатов с учетом входных параметров и выходных данных. И вход, и выход будут простыми типами.

например, нам нужно сгенерировать

int Del(int, int, int, string)

и

int Del2(int, int, string, int)

Любые указания о том, как начать это, были бы очень полезны.

Нам нужно разобрать формулировку, которая представлена ​​в виде xml.

Например, мы представляем (a + b) как

<ADD>
    <param type="decimal">A</parameter>
    <param type="decimal">B</parameter>
</ADD>

Теперь мы хотим, чтобы это было выставлено как Func<decimal, decimal, decimal>. Мы, конечно, хотим разрешить вложенные узлы в xml, например:

(a + b) + (a - b  * (c - d)))

Мы хотим сделать это, используя деревья выражений и Expression.Compile.

Предложения о целесообразности такого подхода приветствуются.

Ответы [ 2 ]

11 голосов
/ 21 апреля 2009

Самый простой способ - использовать существующее семейство делегатов Func.

Используйте typeof(Func<,,,,>).MakeGenericType(...). Например, для вашего int Del2(int, int, string, int) типа:

using System;

class Test
{
    static void Main()
    {
        Type func = typeof(Func<,,,,>);
        Type generic = func.MakeGenericType
            (typeof(int), typeof(int), typeof(string),
             typeof(int), typeof(int));
        Console.WriteLine(generic);
    }
}

Если вам действительно, действительно необходимо создать действительно новый тип, возможно, вы могли бы дать больше контекста, чтобы помочь нам помочь вам лучше.

РЕДАКТИРОВАТЬ: Как говорит Олсин, типы Func являются частью .NET 3.5 - но если вы хотите использовать их в .NET 2.0, вам просто нужно объявить их самостоятельно, например:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>
    (T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>
    (T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Если вам недостаточно 4 аргумента, вы, конечно, можете добавить больше.

0 голосов
/ 21 апреля 2009

Ответ Джона отлично работает, если вы используете Framework 3.5 (но не все).

Ответ 2.0 - использовать Delegate.CreateDelegate (...)

http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx

Сравнение различных способов сделать это, включая Jon's Func, Delegate.CreateDelegate, DynamicMethods и различные другие приемы, обсуждалось в более ранней теме:

Delegate.CreateDelegate vs DynamicMethod vs Expression

-Oisin

...