Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating Delegate Types dynamically in C#

We have a requirement where we need to generate delegate types on the fly. We need to generate delegates given the input parameters and the output. Both input and output would be simple types.

eg, we need to generate

int Del(int, int, int, string)

and

int Del2(int, int, string, int)

Any pointers on how to get started on this would be very helpful.

We need to parse formulate which are represented as xml.

For example, we represent (a + b) as

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

We now want this to be exposed as Func<decimal, decimal, decimal>. We of course want to allow nested nodes in the xml, e.g:

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

We want to do this using expression trees and Expression.Compile.

Suggestions on the feasibility of this approach are welcome.

like image 905
SharePoint Newbie Avatar asked Apr 21 '09 15:04

SharePoint Newbie


1 Answers

The simplest way would be to use the existing Func family of delegates.

Use typeof(Func<,,,,>).MakeGenericType(...). For example, for your int Del2(int, int, string, int) type:

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);
    }
}

If you really, really need to create a genuinely new type, perhaps you could give some more context to help us help you better.

EDIT: As Olsin says, the Func types are part of .NET 3.5 - but if you want to use them in .NET 2.0, you just have to declare them yourself, like this:

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);

If 4 arguments isn't enough for you, you can add more of course.

like image 139
Jon Skeet Avatar answered Oct 16 '22 10:10

Jon Skeet