usar tipos que para metodos funciones funcion expresiones ejemplos delegados delegado como anonimos anonimas c# reflection anonymous-types

tipos - para que usar delegados c#



Pasando tipo anónimo como parámetros del método (9)

En la arquitectura de mi complemento actualmente estoy pasando un nombre de complemento (cadena), nombre de método (cadena) y parámetros (matriz de objetos) a mi servicio de complemento para ejecutar el método especificado y devolver el resultado (de tipo T).

El método de ejecución del servicio plugin se puede ver a continuación:

public TResult Execute<TResult>(string pluginName, string operation, params object[] input) { MethodInfo method = null; TResult result = default(TResult); var plugin = _plugins.Enabled().FirstOrDefault(x => x.GetType().Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase)); if (plugin != null) { method = plugin.GetType().GetMethods().FirstOrDefault(x => x.Name == operation); if (method != null) { result = (TResult)method.Invoke(plugin, input); } } return result; }

Un ejemplo de uso:

var url = AppHelper.PluginService.Execute<string>( "ImagePlugin", "GetImageUrl", new object[] { image, size });

Lo que preferiría hacer es pasar un tipo anónimo en su lugar (ya que creo que esto es más legible), es decir,

var url = AppHelper.PluginService.Execute<string>( "ImagePlugin", "GetImageUrl", new { image = image, targetSize = size });

¿Cómo cambiaría mi método de Ejecución para asignar las propiedades de tipo anónimo a los parámetros de mi método de complemento?

Había considerado usar el nuevo tipo dinámico en .net 4.0, pero prefiero definir mis parámetros en el método del complemento en lugar de aceptar un objeto dinámico.

Gracias ben

[Actualizar]

Después de mirar a través del código fuente de ASP.NET MVC, parece lo suficientemente simple como para colocar el tipo anónimo en un diccionario de objetos, por ejemplo, RouteValueDictionary. Con la ayuda de la reflexión se crea dinámicamente una expresión linq. Aunque es una buena implementación, realmente no quería toda esta complejidad adicional.

Según el comentario a continuación, puedo lograr la legibilidad simplemente especificando mis parámetros en línea (sin necesidad de la declaración de matriz de objetos):

var url = AppHelper.PluginService.Execute<string>("ImagePlugin", "GetImageUrl", image, size);


En primer lugar, verifique el espacio de nombres System.Addin, puede obtener ayuda allí.

En segundo lugar, puede crear una interfaz propia con el nombre y los parámetros específicos del método, y dejar que el complemento implemente la interfaz. Puede definir la interfaz del complemento en un proyecto diferente al que se puede hacer referencia tanto en la aplicación como en el proyecto del complemento.


Este ejemplo convierte un objeto anónimo a un diccionario:

IDictionary<string, object> AnonymousObjectToDictionary(object propertyBag) { var result = new Dictionary<string, object>(); if (propertyBag != null) { foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(propertyBag)) { result.Add(property.Name, property.GetValue(propertyBag)); } } return result; }

Puedes llamarlo así:

AnonymousObjectToDictionary(new { foo = 11, bar = "Be happy" });


Finalmente encontré esta publicación que demuestra el uso de tipos anónimos como diccionarios. Usando este método, puede pasar el tipo anónimo como parámetro de método (objeto) y acceder a sus propiedades.

Sin embargo, también agregaría que después de ver las nuevas características dinámicas en .net 4.0 como ExpandoObject, se siente mucho más limpio pasar un objeto dinámico como parámetro:

dynamic myobj = new ExpandoObject(); myobj.FirstName = "John"; myobj.LastName = "Smith"; SayHello(myobj); ........... public static void SayHello(dynamic properties) { Console.WriteLine(properties.FirstName + " " + properties.LastName); }


Hay algunas maneras de hacer esto posible aunque no aconsejaría a ninguno de ellos.

Primero, puede usar la reflexión, lo que significa que debe escribir muchos códigos adicionales (propensos a errores) en su método PluginService.Execute para obtener los valores que desea.

Segundo, si conoce los parámetros del tipo anónimo que está pasando a su método, puede usar la técnica que se describe here . Puede convertir a otro tipo anónimo dentro de su método que tenga las mismas propiedades. Here hay otra descripción de la misma técnica de Jon Skeet.

Tercero, puedes usar clases del System.ComponentModel . Por ejemplo, ASP.NET MVC usa esto. Utiliza la reflexión bajo el capó. Sin embargo, en ASP.NET MVC, los nombres de propiedades son bien conocidos ( controller y action por ejemplo) o sus nombres no importan porque se pasan como están a un método de controlador (por ejemplo, id ).


Hice esto una vez. Lo que puede hacer es obtener los parámetros esperados de la función a través de la reflexión. Luego, puede construir su matriz de parámetros haciendo coincidir los nombres en la matriz de parámetros con las claves del objeto anónimo.

Espero que ayude :-).



Si se trata de un tipo anónimo de Linq, puede hacerlo fácilmente pasando IEnumerable.

Aquí hay un ejemplo de un método de recepción

public static void MyMethod<IEnumType>(ref IEnumerable<IEnumType> ienum) { using (DataTable dt = new DataTable()) { ienum.First(ie => true).GetType().GetProperties().ToList().ForEach(pr => dt.Columns.Add(pr.Name, typeof(string))); //Parallelization not possible since DataTable columns must be in certain order ienum.ToList().ForEach(ie => //Parallelization not possible since DataTable rows not synchronized. { List<object> objAdd = new List<object>(); ie.GetType().GetProperties().ToList().ForEach(pr => objAdd.Add(ie.GetType().InvokeMember(pr.Name, BindingFlags.GetProperty, null, ie, null))); //Parallelization not possible since DataTable columns must be in certain order dt.Rows.Add(objAdd.ToArray()); objAdd.Clear(); objAdd = null; }); //Do something fun with dt } }

Por supuesto, ya que estás utilizando la reflexión, es posible que veas problemas de rendimiento en machiens más lentos o donde tienes un IEnumerable grande o muchas propiedades en T.


Utilice el objeto dinámico para los parámetros si desea pasar un tipo anónimo. El método de ejecución de un complemento debe esperar ciertas propiedades de un objeto de parámetro para que funcione. Al utilizar la palabra clave dinámica, se le indicará al compilador C # que no realice una verificación de tipo en un parámetro y le permitirá usar una sintaxis fuertemente tipada en el código del complemento. La resolución del nombre de las propiedades se realizará en tiempo de ejecución y, si un objeto pasado no tuviera tales propiedades, se lanzará una excepción.

var o = new { FirstName = "John", LastName = "Doe" }; var result = MyMethod(o); string MyMethod(dynamic o) { return o.FirstName + " " + o.LastName; }

Lee más en esta entrada de blog


public static void ExAnonymousType() { var nguoi = new { Ten = "Vinh", Tuoi = 20 }; Console.WriteLine(nguoi.Ten + " " + nguoi.Tuoi); DoSomeThing(nguoi); } private static void DoSomeThing(object nguoi) { Console.WriteLine(nguoi.GetType().GetProperty("Ten").GetValue(nguoi,null)); }