This article has been localized into Spanish by the community.
El ExpandoObject
Como vimos en un artículo anterior, podemos usar la palabra clave dynamic para mantener un objeto donde podamos definir las propiedades, sin tener que definir primero la clase. Lo que no podemos hacer con un objeto dinámico es agregarle propiedades dinámicamente después de que el objeto se haya inicializado. Si necesita esta habilidad específica, C# viene con una solución para ti: el ExpandoObject. Saltemos directamente al ejemplo, para que veas lo fácil de usar:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = "New York";
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown);
Notarás que declaro el objeto con el tipo dinámico, a pesar de que inicie una instancia ExpandoObject. La razón es que si el objeto se declara como un ExpandoObject, el compilador lo comprobará e inmediatamente se quejará de la falta de las propiedades que inventamos para él (Nombre, Edad, etc.). Podemos evitar esto declarándolo como una dinámica, que como aprendimos en el artículo anterior, evitará que el compilador verifique la existencia de las propiedades que utilizamos.
Una cosa interesante es que, por supuesto, un ExpandoObject puede tener propiedades que también son ExpandoObject, lo que le permite crear tipos complejos sobre la marcha, como en este ejemplo:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = new System.Dynamic.ExpandoObject();
user.HomeTown.Name = "New York";
user.HomeTown.ZipCode = 10001;
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]");
Simplemente cambio la propiedad HomeTown de una cadena a un ExpandoObject, y luego le agrego propiedades, en este caso el nombre y el código postal de la ciudad. Pero no tiene que terminar con esto: incluso podemos agregar métodos al objeto, nuevamente sobre la marcha, usando algunos trucos bastante sofisticados:
user.DescribeUser = (Func<String>)(() => {
return user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]";
});
Console.WriteLine(user.DescribeUser());
Bastante bueno, pero ¿qué es realmente un ExpandoObject? Implementa varias interfaces interesantes, pero una de ellas es IDictionary<string, object> - esto significa todo el azúcar sintáctico, su ExpandoObject es básicamente un diccionario que contiene valores de objetos basados en claves de cadena. Eso también significa que iterar sobre un ExpandoObject es tan fácil como iterar a través de un Diccionario regular. Esto es muy práctico:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
foreach (KeyValuePair<string, object> kvp in user)
{
Console.WriteLine(kvp.Key + ": " + kvp.Value);
}
Resumen
El tipo ExpandoObject le permite definir objetos sobre la marcha y luego agregarle propiedades cuando lo desee. Dado que es básicamente un tipo dinámico, hereda las mismas ventajas y desventajas que discutimos en el artículo anterior. Sin embargo, como beneficio adicional, ExpandoObject implementa la interfaz INotifyPropertyChanged, que definitivamente apreciará si está utilizando, WPF para tu aplicación.