property example dynamically create c# .net .net-4.0 c#-4.0

dynamically - expandoobject c# example



¿Cuáles son los verdaderos beneficios de ExpandoObject? (10)

Creo que tendrá un beneficio sintáctico, ya que ya no estará "falsificando" propiedades agregadas dinámicamente usando un diccionario.

Eso, y la interoperabilidad con lenguajes dinámicos lo pensaría.

La clase ExpandoObject se agrega a .NET 4 le permite establecer arbitrariamente propiedades en un objeto en tiempo de ejecución.

¿Hay alguna ventaja sobre esto al usar un Dictionary<string,object> , o incluso un Hashtable ? Por lo que puedo decir, esto no es más que una tabla hash a la que puedes acceder con una sintaxis un poco más concisa.

Por ejemplo, ¿por qué es esto:

dynamic obj = new ExpandoObject(); obj.MyInt = 3; obj.MyString = "Foo"; Console.WriteLine(obj.MyString);

Realmente mejor, o sustancialmente diferente, que:

var obj = new Dictionary<string, object>(); obj["MyInt"] = 3; obj["MyString"] = "Foo"; Console.WriteLine(obj["MyString"]);

¿Qué ventajas reales se obtienen al usar ExpandoObject en lugar de usar un tipo de diccionario arbitrario, además de no ser obvio que está usando un tipo que se determinará en el tiempo de ejecución?


Desde que escribí el artículo de MSDN al que te refieres, supongo que debo responder este.

Primero, anticipé esta pregunta y es por eso que escribí una publicación de blog que muestra un caso de uso más o menos real para ExpandoObject: Dynamic in C # 4.0: Introducing the ExpandoObject .

En breve, ExpandoObject puede ayudarlo a crear objetos jerárquicos complejos. Por ejemplo, imagina que tienes un diccionario dentro de un diccionario:

Dictionary<String, object> dict = new Dictionary<string, object>(); Dictionary<String, object> address = new Dictionary<string,object>(); dict["Address"] = address; address["State"] = "WA"; Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

Cuanto más profunda es la jerarquía, más feo es el código. Con ExpandoObject se mantiene elegante y legible.

dynamic expando = new ExpandoObject(); expando.Address = new ExpandoObject(); expando.Address.State = "WA"; Console.WriteLine(expando.Address.State);

En segundo lugar, como ya se señaló, ExpandoObject implementa la interfaz INotifyPropertyChanged que le brinda más control sobre las propiedades que un diccionario.

Finalmente, puedes agregar eventos a ExpandoObject como aquí:

class Program { static void Main(string[] args) { dynamic d = new ExpandoObject(); // Initialize the event to null (meaning no handlers) d.MyEvent = null; // Add some handlers d.MyEvent += new EventHandler(OnMyEvent); d.MyEvent += new EventHandler(OnMyEvent2); // Fire the event EventHandler e = d.MyEvent; if (e != null) { e(d, new EventArgs()); } // We could also fire it with... // d.MyEvent(d, new EventArgs()); // ...if we knew for sure that the event is non-null. } static void OnMyEvent(object sender, EventArgs e) { Console.WriteLine("OnMyEvent fired by: {0}", sender); } static void OnMyEvent2(object sender, EventArgs e) { Console.WriteLine("OnMyEvent2 fired by: {0}", sender); } }


Después de valueTuples, ¿para qué sirve la clase ExpandoObject? este código de 6 líneas con ExpandoObject:

dynamic T = new ExpandoObject(); T.x = 1; T.y = 2; T.z = new ExpandoObject(); T.z.a = 3; T.b= 4;

Se puede escribir en una línea con tuplas:

var T = (x: 1, y: 2, z: (a: 3, b: 4));

además de con la sintaxis de tuplas, tiene una fuerte inferencia de tipos y soporte intlisense


El beneficio real para mí es el enlace de datos totalmente sin esfuerzo de XAML:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

<TextBlock Text="{Binding SomeData.WhatEver}" />


Es un ejemplo de un excelente artículo de MSDN sobre el uso de ExpandoObject para crear tipos dinámicos ad-hoc para datos estructurados entrantes (es decir, XML, Json).

También podemos asignar delegado a la propiedad dinámica de ExpandoObject :

dynamic person = new ExpandoObject(); person.FirstName = "Dino"; person.LastName = "Esposito"; person.GetFullName = (Func<String>)(() => { return String.Format("{0}, {1}", person.LastName, person.FirstName); }); var name = person.GetFullName(); Console.WriteLine(name);

Por lo tanto, nos permite inyectar algo de lógica en un objeto dinámico en tiempo de ejecución. Por lo tanto, junto con las expresiones lambda, los cierres, las palabras clave dinámicas y la clase DynamicObject , podemos introducir algunos elementos de programación funcional en nuestro código C #, que conocemos de lenguajes dinámicos como JavaScript o PHP.


Hay algunos casos en que esto es útil. Lo usaré para un shell modularizado, por ejemplo. Cada módulo define su propio diálogo de configuración vinculado a su configuración. Le proporciono un ExpandoObject como Datacontext y guardo los valores en mi configuración Almacenamiento. De esta manera, el escritor del diálogo de configuración solo tiene que vincularse a un valor y se crea y guarda automáticamente. (Y proporcionado al módulo para el uso de estos ajustes de curso)

Es simplemente más fácil de usar que un diccionario. Pero todos deben ser conscientes de que internamente es solo un Diccionario.

Es como el azúcar sintáctico LINQ, pero a veces hace las cosas más fáciles.

Entonces, para responder a su pregunta directamente: es más fácil de escribir y más fácil de leer. Pero técnicamente es esencialmente un Dictionary<string,object> (Incluso puede convertirlo en uno para enumerar los valores).


La interoperabilidad con otros idiomas basados ​​en el DLR es la razón número 1 por la que puedo pensar. No puede pasarles un Dictionary<string, object> ya que no es un IDynamicMetaObjectProvider . Otro beneficio adicional es que implementa INotifyPropertyChanged que significa que en el mundo de enlace de datos de WPF también tiene beneficios adicionales más allá de lo que el Dictionary<K,V> puede proporcionarle.


Se trata de la conveniencia del programador. Me imagino escribiendo programas rápidos y sucios con este objeto.


Una ventaja es para escenarios vinculantes. Las cuadrículas de datos y las cuadrículas de propiedades recogerán las propiedades dinámicas a través del sistema TypeDescriptor. Además, el enlace de datos de WPF comprenderá las propiedades dinámicas, por lo que los controles de WPF se pueden enlazar a un ExpandoObject más fácilmente que un diccionario.

La interoperabilidad con idiomas dinámicos, que esperarán propiedades DLR en lugar de entradas de diccionario, también puede ser una consideración en algunos escenarios.


var obj = new Dictionary<string, object>; ... Console.WriteLine(obj["MyString"]);

Creo que solo funciona porque todo tiene un ToString (), de lo contrario tendrías que saber el tipo que era y lanzar el ''objeto'' a ese tipo.

Algunos de estos son útiles más a menudo que otros, estoy tratando de ser minucioso.

  1. Puede ser mucho más natural acceder a una colección, en este caso lo que efectivamente es un "diccionario", usando la notación de puntos más directa.

  2. Parece que esto podría ser usado como un Tuple realmente agradable. Aún puedes llamar a tus miembros "Item1", "Item2" etc ... pero ahora no tienes que hacerlo, también es mutable, a diferencia de un Tuple. Esto tiene el gran inconveniente de la falta de soporte inteligente.

  3. Puede sentirse incómodo con los "nombres de miembros como cadenas", como se siente en el diccionario, puede sentir que es demasiado parecido a "ejecutar cadenas", y puede llevar a que las convenciones de nombres se codifiquen, y se trate de trabajar con morfemas y sílabas cuando el código está intentando entender cómo usar miembros :-P

  4. ¿Puede asignar un valor a un ExpandoObject en sí o simplemente a sus miembros? Compare y contraste con dinámico / dinámico [], use el que mejor se adapte a sus necesidades.

  5. No creo que dinámico / dinámico [] funcione en un bucle foreach, tienes que usar var, pero posiblemente puedas usar ExpandoObject.

  6. No puede usar la dinámica como un miembro de datos en una clase, tal vez porque es al menos una especie de palabra clave, con suerte puede hacerlo con ExpandoObject.

  7. Espero que "es" un ExpandoObject, podría ser útil para etiquetar cosas muy genéricas aparte, con un código que se diferencia según los tipos en los que se utilizan muchas cosas dinámicas.

Sé bueno si pudieras profundizar en varios niveles a la vez.

var e = new ExpandoObject(); e.position.x = 5; etc...

Ese no es el mejor ejemplo posible, imagine usos elegantes según sea apropiado en sus propios proyectos.

Es una pena que no pueda hacer que el código construya algunos de estos y empuje los resultados a inteligencia. Aunque no estoy seguro de cómo funcionaría esto.

Ser amable si podrían tener un valor, así como miembros.

var fifteen = new ExpandoObject(); fifteen = 15; fifteen.tens = 1; fifteen.units = 5; fifteen.ToString() = "fifteen"; etc...