2009-04-21 5 views
5

Tenemos un requisito en el que necesitamos generar tipos de delegados sobre la marcha. Necesitamos generar delegados dados los parámetros de entrada y la salida. Tanto la entrada como la salida serían tipos simples.Generación de tipos de delegados dinámicamente en C#

por ejemplo, tenemos que generar

int Del(int, int, int, string) 

y

int Del2(int, int, string, int) 

Cualquier punteros sobre cómo empezar a trabajar en esto sería muy útil.

Tenemos que analizar fórmulas que se representan como xml.

Por ejemplo, nos representan (a + b) como

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

Ahora queremos que esto se expone como Func<decimal, decimal, decimal>. Por supuesto, nosotros queremos permitir que los nodos anidados en el xml, por ejemplo:

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

que queremos hacer esto utilizando árboles de expresión y Expression.Compile.

Sugerencias sobre la viabilidad de este enfoque son bienvenidas.

Respuesta

10

La manera más simple sería utilizar la familia de delegados Func existente.

Use typeof(Func<,,,,>).MakeGenericType(...). Por ejemplo, para el tipo de 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); 
    } 
} 

Si realmente, realmente necesita crear un nuevo tipo de verdad, tal vez podría darle un poco más de contexto para ayudarnos a ayudarle mejor.

EDIT: Como dice Olsin, los Func tipos son parte de .NET 3.5 - pero si desea utilizarlos en .NET 2.0, sólo hay que declarar su propia cuenta, de esta manera:

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

Si 4 argumentos no son suficientes para usted, puede agregar más, por supuesto.

+0

Hola, publicado una edición con el requisito –

+0

A B es un ejemplo. Queremos crear un método invocable a partir de esto en tiempo de ejecución. –

+0

Me temo que realmente no nos has dado suficiente información sobre cuál es el problema o el enfoque para poder juzgar si es una buena idea o no. Usar árboles de expresión en general suena como un enfoque razonable, pero no estoy muy seguro de cómo encaja el resto de tu pregunta en eso. –

0

La respuesta de Jon funciona bien si está ejecutando Framework 3.5 (pero no todos lo son).

2.0 La respuesta es utilizar Delegate.CreateDelegate (...)

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

se discutió Una comparación de varias maneras de hacer esto incluyendo Jon Func, Delegate.CreateDelegate, DynamicMethods y varios otros trucos en un hilo anterior:

Delegate.CreateDelegate vs DynamicMethod vs Expression

-Oisin

+3

Delegate.CreateDelegate crea una * instancia * de un tipo de delegado, no el tipo en sí. –

+0

oops, por supuesto. f00f. – x0n