Dynamisches Hinzufügen von Eigenschaften zu einem ExpandoObject


232

Ich möchte einem ExpandoObject zur Laufzeit dynamisch Eigenschaften hinzufügen. Um beispielsweise einen String-Eigenschaftsaufruf NewProp hinzuzufügen, möchte ich so etwas schreiben

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

Ist das leicht möglich?


Antworten:


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

Alternative:

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

31
Ich habe nie bemerkt, dass Expando IDictionary <string, object> implementiert . Ich habe immer gedacht, dass die Besetzung es in ein Wörterbuch kopieren würde. Durch Ihren Beitrag wurde mir jedoch klar, dass Sie beim Ändern des Wörterbuchs auch das zugrunde liegende ExpandoObject ändern! Vielen Dank
Dynalon

3
bekommenError 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

23
Es ist IDictionary<string, object>nicht IDictionary<string, string>.
Stephen Cleary

3
@ user123456: Eigenschaftsnamen sind immer Zeichenfolgen. Sie können nicht dynamisch sein. Wenn mit "ist eine Dynamik" gemeint ist "ist erst zur Laufzeit bekannt", müssen Sie das zweite Beispiel verwenden. Wenn von „ein dynamischer ist“, können Sie die Eigenschaft bedeuten Wert ist dynamisch, dann ist das in Ordnung. Ein dynamischer Wert funktioniert in beiden Beispielen einwandfrei.
Stephen Cleary

3
Es ist wichtig zu beachten, dass Sie beim Casting IDictionarynicht dynamicals Variablentyp verwenden.
user3791372


14

Hier ist eine Beispiel-Hilfsklasse, die ein Objekt konvertiert und ein Expando mit allen öffentlichen Eigenschaften des angegebenen Objekts zurückgibt.


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

Verwendung:

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

//Add Custom Properties
dynamicHelper.AddProperty(expandoObj, "dynamicKey", "Some Value");

10
"var expandoDict = expando als IDictionary;" Diese Zeile muss in "var expandoDict = expando as IDictionary <String, object>;" geändert werden.
Jom George

0

Ich denke, dies fügt eine neue Eigenschaft im gewünschten Typ hinzu, ohne einen primitiven Wert festlegen zu müssen, wie wenn die Eigenschaft in der Klassendefinition definiert ist

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

5
Hey Morteza! Nur-Code-Antworten können das Problem lösen, aber sie sind viel nützlicher, wenn Sie erklären, wie sie es lösen. Community erfordert sowohl Theorie als auch Code, um Ihre Antwort vollständig zu verstehen.
RBT
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.