2009-11-02 16 views
5

Con la introducción de cosas como la mecanografía de pato, me encantaría si compongo métodos de objetos sobre la marcha, además de los métodos de extensión. Alguien sabe si esto es posible? Sé que a MS le preocupa componer framework sobre la marcha, pero parece que están sumergiendo sus pies en el agua.C# 4.0, ¿Métodos sobre la marcha?

Actualización: Gracias a Pavel por aclarar. Por ejemplo, digamos que devuelvo un nuevo objeto dinámico de LINQ y me gustaría agregarle algunos métodos sobre la marcha.

+0

¿Quieres decir la generación de código runtieme? ¿O te refieres a agregar métodos dinámicamente a los objetos, a la JavaScript? –

+0

El más tarde. Parece que puedes hacerlo con árboles de expresión, pero qué PITA. – Trent

Respuesta

11

En vista de la respuesta actualizada, en realidad estás no en busca de "métodos dinámicos", tanto como "objetos dinámicos" - de tal manera que es posible añadir nuevas propiedades y métodos para ellos en tiempo de ejecución. Si esto es correcto, entonces en .NET 4.0, se puede utilizar en conjunción con ExpandoObjectdynamic:

dynamic foo = new ExpandoObject(); 
foo.Bar = 123; // creates a new property on the fly 
int x = foo.Bar; // 123 

// add a new method (well, a delegate property, but it's callable as method) 
foo.Baz = (Func<int, int, int>) 
    delegate(int x, int y) 
    { 
     return x + y; 
    }; 

foo.Baz(1, 2); // 3 

se puede tener "métodos dinámicos", también, con los árboles de expresión, y una vez que obtener un delegado para tal método , también puede crear una propiedad similar a un método invocable en un ExpandoObject.

Para utilizar en consultas LINQ, desafortunadamente, no puede usar los inicializadores de objetos con ExpandoObject; en el caso más sencillo, lo siguiente no se compilará:

var foo = new ExpandoObject { Bar = 123; } 

La razón es que Bar en este caso se buscará de forma estática como una propiedad de ExpandoObject. Necesita que el receptor sea dynamic para que esta característica se active, y no hay forma de hacerlo dentro de un inicializador de objetos. Como una solución para su uso en LINQ, considerar este método de extensión ayudante:

public static dynamic With(this ExpandoObject o, Action<dynamic> init) 
{ 
    init(o); 
    return o; 
} 

Ahora puede utilizar así:

from x in xs 
select new ExpandoObject().With(o => { 
    o.Foo = x; 
    o.Bar = (Func<int, int>)delegate(int y) { return x + y; }; 
}); 
+0

¡Agradable! ¿Qué sucede si creé un objeto dinámico con LINQ (devolver propiedades especificadas), es un ExpandoObject al que puedo agregar métodos? – Trent

+0

Los tipos anónimos (creados a través de 'new {...}' sin clase especificada después de 'new') no son expandidos. Para el resto de la historia, revisa la respuesta editada. –

+0

Eso es un buen trabajo. Solo algunas correcciones de sintaxis para compilar esto. Reemplace Acción <> con Func <>, y necesita poner ';' después de creaciones dinámicas de propiedad/método en lugar de ',' – Trent

1

Esto ya fue posible con la ayuda de DynamicMethod y/o MethodBuilder. No estoy seguro si eso cuenta por estar "preocupado", ya que ha existido desde hace un tiempo, aunque requiere un ensamblaje dinámico en la mayoría de los escenarios (sin embargo, DynamicMethod se puede usar sin).

+0

Cuando digo preocupado, me refiero a este http://blogs.msdn.com/csharpfaq/archive/2004/03/09/86979.aspx. Esperaba evitar la reflexión, pero gracias por la sugerencia – Trent

+0

lo siento, el juego de palabras fue un poco intencionado. Como has descubierto, no es necesario usar el reflejo. ¡Buena respuesta, Pavel escribió! – Abel

Cuestiones relacionadas