Динамическое добавление свойств в ExpandoObject

233

Я хотел бы динамически добавлять свойства ExpandoObject во время выполнения. Так, например, чтобы добавить свойство свойства строки NewProp, я хотел бы написать что-то вроде

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

Это легко возможно?

Craig
источник

Ответы:

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

В качестве альтернативы:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);
Стивен Клири
источник
32
Я никогда не понимал, что Expando реализует IDictionary <string, object>. Я всегда думал, что актерский состав скопирует его в словарь. Тем не менее, ваше сообщение заставило меня понять, что если вы измените словарь, вы также измените базовый ExpandoObject! Большое спасибо
Dynalon
3
получениеError 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
Это IDictionary<string, object>не так IDictionary<string, string>.
Стивен Клири
3
@ user123456: имена свойств всегда являются строками; они не могут быть динамичными. Если под «динамическим» подразумевается «неизвестно до времени выполнения», то вам нужно использовать второй пример. Если под «динамическим» подразумевается значение свойства « динамическое», то это нормально. Наличие динамического значения прекрасно работает для любого примера.
Стивен Клири
3
Важно отметить, что когда вы используете приведение IDictionary, вы не используете dynamicтип переменной.
user3791372
14

Вот пример вспомогательного класса, который преобразует объект и возвращает Expando со всеми открытыми свойствами данного объекта.


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

Использование:

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

//Add Custom Properties
dynamicHelper.AddProperty(expandoObj, "dynamicKey", "Some Value");
Johannes
источник
11
"var expandoDict = раскрыть как IDictionary;" эту строку нужно изменить на "var expandoDict = expando как IDictionary <String, object>;"
Джом Джордж
0

я думаю, что это добавить новое свойство в желаемом типе без необходимости устанавливать примитивное значение, как, когда свойство определено в определении класса

var x = new ExpandoObject();
x.NewProp = default(string)
Мортеза Эбрахим Неджад
источник
5
Привет, Мортеза! Ответы только на код могут решить проблему, но они гораздо полезнее, если вы объясните, как они решают эту проблему. Сообщество требует теории и кода, чтобы полностью понять ваш ответ.
RBT