Dynamiczne dodawanie właściwości do obiektu ExpandoObject


233

Chciałbym dynamicznie dodawać właściwości do ExpandoObject w czasie wykonywania. Na przykład, aby dodać wywołanie właściwości string NewProp, chciałbym napisać coś takiego

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

Czy to jest możliwe?


Odpowiedzi:


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

Alternatywnie:

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

32
Nigdy nie zdawałem sobie sprawy, że Expando implementuje IDictionary <ciąg, obiekt>. Zawsze myślałem, że obsada skopiuje go do słownika. Jednak twój post uświadomił mi, że jeśli zmienisz Słownik, zmienisz także ExpandoObject!
Wielkie

3
uzyskiwanieError 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
To IDictionary<string, object>nie IDictionary<string, string>.
Stephen Cleary

3
@ user123456: Nazwy właściwości są zawsze ciągami; nie mogą być dynamiczne. Jeśli przez „jest dynamiczny”, masz na myśli „nie jest znany do czasu uruchomienia”, musisz użyć drugiego przykładu. Jeśli przez „jest dynamiczny”, masz na myśli, że wartość właściwości jest dynamiczna, to w porządku. Posiadanie wartości dynamicznej działa dobrze w obu przypadkach.
Stephen Cleary

3
Ważne jest, aby pamiętać, że podczas przesyłania jako IDictionarytakiego nie używasz dynamicjako typu zmiennej.
user3791372


14

Oto przykładowa klasa pomocnicza, która konwertuje obiekt i zwraca Expando ze wszystkimi publicznymi właściwościami danego obiektu.


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

Stosowanie:

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

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

11
„var expandoDict = expando jako IDictionary;” wiersz ten należy zmienić na „var expandoDict = expando as IDictionary <String, object>;”
Jom George,

0

myślę, że to dodaje nową właściwość w pożądanym typie bez konieczności ustawiania pierwotnej wartości, na przykład gdy właściwość zdefiniowana w definicji klasy

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

5
Hej Morteza! Odpowiedzi zawierające tylko kod mogą rozwiązać problem, ale są o wiele bardziej przydatne, jeśli wyjaśnisz, w jaki sposób je rozwiązują. Społeczność wymaga zarówno teorii, jak i kodu, aby w pełni zrozumieć twoją odpowiedź.
RBT
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.