Transmitir a tipo anónimo

Tuve el siguiente problema hoy, y me preguntaba si hay una solución para mi problema.

Mi idea era crear clases anónimas y usarla como fuente de datos para WinForm BindingSource:

public void Init() { var option1 = new { Id = TemplateAction.Update, Option = "Update the Templates", Description = "Bla bla 1." }; var option2 = new { Id = TemplateAction.Download, Option = "Download the Templates", Description = "Bla bla 2." }; var list = new[] {option1, option2}.ToList(); bsOptions.DataSource = list; // my BindingSource // cboTemplates is a ComboBox cboTemplates.DataSource = bsOptions; cboTemplates.ValueMember = "Id"; cboTemplates.DisplayMember = "Option"; lblInfoTemplates.DataBindings.Add("Text", bsOptions, "Description"); } 

Eso funciona bien hasta ahora.

El problema que tuve fue sacar Id de la propiedad “Actual” de BindingSource, porque no puedo devolverlo al Tipo anónimo:

 private void cmdOK_Click(object sender, EventArgs e) { var option = (???)bsOptions.Current; } 

Supongo que no hay forma de averiguar el tipo de “Actual” y acceder a la propiedad “Id”. Tal vez alguien tiene una buena solución …

Sé que hay otras (y también mejores) maneras de obtener el Id (Reflexión, leer el valor del ComboBox, no usar tpyes anónimos, …) Solo estoy cómico si es posible obtener el Tipo de bsOptions. Actual de una manera elegante.

Tenga en cuenta que , según el comentario, me gustaría señalar que yo también recomiendo usar un tipo real cuando necesita pasarlo por el progtwig de esta manera. Los tipos anónimos solo deberían usarse localmente de una sola vez (en mi opinión), pero de todos modos, aquí está el rest de mi respuesta.


Puedes hacerlo usando un truco, engañando al comstackdor para que infiera el tipo correcto para ti:

 using System; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var a = new { Id = 1, Name = "Bob" }; TestMethod(a); Console.Out.WriteLine("Press enter to exit..."); Console.In.ReadLine(); } private static void TestMethod(Object x) { // This is a dummy value, just to get 'a' to be of the right type var a = new { Id = 0, Name = "" }; a = Cast(a, x); Console.Out.WriteLine(a.Id + ": " + a.Name); } private static T Cast(T typeHolder, Object x) { // typeHolder above is just for compiler magic // to infer the type to cast x to return (T)x; } } } 

El truco está en que dentro del ensamblaje, el mismo tipo anónimo (mismas propiedades, el mismo orden) se resuelve en el mismo tipo, lo que hace que el truco anterior funcione.

 private static T CastTo(this Object value, T targetType) { // targetType above is just for compiler magic // to infer the type to cast x to return (T)x; } 

uso:

 var value = x.CastTo(a); 

Pero estamos realmente empujando los límites aquí. Use un tipo real, se verá y se sentirá más limpio también.

En lugar de transmitir a su tipo personalizado intente usar el tipo dynamic.

Su controlador de eventos se vería así:

 private void cmdOK_Click(object sender, EventArgs e) { dynamic option = bsOptions.Current; if (option.Id == 1) { doSomething(); } else { doSomethingElse(); } } 

Para citar a MSDN :

Un tipo anónimo no se puede convertir a ninguna interfaz o tipo excepto objeto.

En C # 3.0, esto no es posible. Tendrá que esperar C # 4.0, que permite acceder a las propiedades en tiempo de ejecución utilizando variables “dinámicas”.

puedes probar esto:

 private void cmdOK_Click(object sender, EventArgs e) { var option = Cast(bsOptions.Current, new { Id = 0, Option = "", Description = "" }); } 

ver: no se puede devolver el tipo anónimo del método? De Verdad?

 public class MyExtensMethods{ public static T GetPropertyValue(this Object obj, string property) { return (T)obj.GetType().GetProperty(property).GetValue(obj, null); } } class SomeClass { public int ID{get;set;} public int FullName{get;set;} } // casts obj to type SomeClass public SomeClass CastToSomeClass(object obj) { return new SomeClass() { ID = obj.GetPropertyValue("Id"), FullName = obj.GetPropertyValue("LastName") + ", " + obj.GetPropertyValue("FirstName") }; } 

…. luego de lanzarlo harás:

 var a = new { Id = 1, FirstName = "Bob", LastName="Nam" }; SomeClass myNewVar = CastToSomeClass(a); 

También puede declarar una matriz de Tipos anónimos directamente con esa syntax:

 var data = new [] { new {Id = 0, Name = "Foo"}, new {Id = 42, Name = "Bar"}, };