Agregar dinámicamente propiedades a un ExpandoObject

Respuestas:

489
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;

Alternativamente:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);
Stephen Cleary
fuente
32
Nunca me he dado cuenta de que Expando implementa IDictionary <string, object>. Siempre pensé que ese elenco lo copiaría a un diccionario. Sin embargo, su publicación me hizo comprender que si cambia el Diccionario, ¡también cambia el ExpandoObject subyacente! Muchas gracias
Dynalon
3
gettingError 53 Cannot convert type 'System.Dynamic.ExpandoObject' to 'System.Collections.Generic.IDictionary<string,string>' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
TheVillageIdiot
24
Es IDictionary<string, object>, no IDictionary<string, string>.
Stephen Cleary
3
@ user123456: los nombres de propiedad son siempre cadenas; No pueden ser dinámicos. Si por "es una dinámica", quiere decir "no se conoce hasta el tiempo de ejecución", entonces debe usar el segundo ejemplo. Si por "es una dinámica", quiere decir que el valor de la propiedad es dinámico, entonces está bien. Tener un valor dinámico funciona bien para cualquier ejemplo.
Stephen Cleary
3
Es importante tener en cuenta que cuando se realiza la conversión IDictionary, no se usa dynamiccomo tipo de variable.
user3791372
14

Aquí hay una clase auxiliar de muestra que convierte un Objeto y devuelve un Expando con todas las propiedades públicas del objeto dado.


    public static class dynamicHelper
        {
            public static ExpandoObject convertToExpando(object obj)
            {
                //Get Properties Using Reflections
                BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
                PropertyInfo[] properties = obj.GetType().GetProperties(flags);

                //Add Them to a new Expando
                ExpandoObject expando = new ExpandoObject();
                foreach (PropertyInfo property in properties)
                {
                    AddProperty(expando, property.Name, property.GetValue(obj));
                }

                return expando;
            }

            public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
            {
                //Take use of the IDictionary implementation
                var expandoDict = expando as IDictionary;
                if (expandoDict.ContainsKey(propertyName))
                    expandoDict[propertyName] = propertyValue;
                else
                    expandoDict.Add(propertyName, propertyValue);
            }
        }

Uso:

//Create Dynamic Object
dynamic expandoObj= dynamicHelper.convertToExpando(myObject);

//Add Custom Properties
dynamicHelper.AddProperty(expandoObj, "dynamicKey", "Some Value");
Johannes
fuente
11
"var expandoDict = expando como IDictionary;" esta línea debe cambiar a "var expandoDict = expando como IDictionary <String, object>;"
Jom George
0

Creo que esto agrega una nueva propiedad en el tipo deseado sin tener que establecer un valor primitivo, como cuando la propiedad se define en la definición de clase

var x = new ExpandoObject();
x.NewProp = default(string)
Morteza ebrahim nejad
fuente
55
¡Hola Morteza! Las respuestas de solo código pueden resolver el problema, pero son mucho más útiles si explica cómo lo resuelven. La comunidad requiere tanto teoría como código para comprender su respuesta por completo.
RBT