Aggiunta dinamica di proprietà a un ExpandoObject


233

Vorrei aggiungere dinamicamente le proprietà a un ExpandoObject in fase di esecuzione. Quindi, ad esempio, per aggiungere una proprietà della stringa chiamata NewProp, vorrei scrivere qualcosa del genere

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

Questo è facilmente possibile?


Risposte:


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

In alternativa:

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

32
Non ho mai capito che Expando implementasse IDictionary <stringa, oggetto>. Ho sempre pensato che quel cast lo avrebbe copiato su un dizionario. Tuttavia, il tuo post mi ha fatto capire che se cambi il Dizionario, cambi anche il ExpandoObject sottostante! Grazie mille
Dynalon,

3
ottenereError 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
Non lo IDictionary<string, object>è IDictionary<string, string>.
Stephen Cleary,

3
@ user123456: i nomi delle proprietà sono sempre stringhe; non possono essere dinamici. Se per "è una dinamica", vuoi dire "non è noto fino al runtime", allora devi usare il secondo esempio. Se per "è una dinamica", intendi che il valore della proprietà è dinamico, allora va bene. Avere un valore dinamico funziona bene per entrambi gli esempi.
Stephen Cleary,

3
È importante notare che quando si esegue il casting in quanto IDictionarynon si utilizza dynamiccome tipo di variabile.
user3791372


14

Ecco una classe helper di esempio che converte un oggetto e restituisce un Expando con tutte le proprietà pubbliche dell'oggetto specificato.


    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 come IDictionary;" questa riga deve cambiare in "var expandoDict = expando come IDictionary <String, object>;"
Jom George,

0

penso che questo aggiunga una nuova proprietà nel tipo desiderato senza dover impostare un valore primitivo, come quando la proprietà è definita nella definizione della classe

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

5
Ehi Morteza! Le risposte di solo codice possono risolvere il problema, ma sono molto più utili se spieghi come risolverlo. La community richiede sia la teoria che il codice per comprendere appieno la tua risposta.
RBT
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.