Adicionando propriedades dinamicamente a um ExpandoObject


233

Gostaria de adicionar dinamicamente propriedades a um ExpandoObject em tempo de execução. Por exemplo, para adicionar uma propriedade de string, chame NewProp, gostaria de escrever algo como

var x = new ExpandoObject();
x.AddProperty("NewProp", System.String);

Isso é facilmente possível?


Respostas:


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

Alternativamente:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);

32
Eu nunca percebi que o Expando implementa o IDictionary <string, object>. Eu sempre pensei que o elenco iria copiá-lo para um dicionário. No entanto, sua postagem me fez entender que, se você alterar o Dicionário, também altera o ExpandoObject! Muito obrigado
Dynalon

3
ObtendoError 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 30/10/12

24
É IDictionary<string, object>, não IDictionary<string, string>.
precisa

3
@ user123456: Os nomes das propriedades são sempre strings; eles não podem ser dinâmicos. Se por "é uma dinâmica", você quer dizer "não é conhecido até o tempo de execução", é necessário usar o segundo exemplo. Se por "é uma dinâmica", você quer dizer que o valor da propriedade é dinâmico, tudo bem. Ter um valor dinâmico funciona bem para qualquer exemplo.
Stephen Cleary

3
É importante observar que, quando você está transmitindo, IDictionarynão usa dynamiccomo tipo de variável.
User3791372


14

Aqui está uma classe auxiliar de amostra que converte um Objeto e retorna um Expando com todas as propriedades públicas do objeto especificado.


    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");

11
"var expandoDict = expando como IDictionary;" essa linha precisa mudar para "var expandoDict = expando como IDictionary <String, objeto>;"
precisa

0

Eu acho que isso adicionar nova propriedade no tipo desejado sem ter que definir um valor primitivo, como quando a propriedade definida na definição de classe

var x = new ExpandoObject();
x.NewProp = default(string)

5
Ei Morteza! Respostas somente de código podem resolver o problema, mas são muito mais úteis se você explicar como elas o resolvem. A comunidade requer teoria e código para entender sua resposta completamente.
RBT
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.