Динамічне додавання властивостей до ExpandoObject


233

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

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

Це легко можливо?


Відповіді:


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 <рядок, об'єкт>. Я завжди думав, що кастинг скопіює його до словника. Однак, ваша публікація дала мені зрозуміти, що якщо ви зміните словник, ви також зміните базовий ExpandoObject! Велике спасибі
Диналону

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як тип змінної.
користувач3791372


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

11
"var expandndoDict = extendo як IDictionary;" цей рядок потрібно змінити на "var expandndoDict = extendo як IDictionary <String, object>;"
Джом Джордж

0

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

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

5
Гей, Мортеза! Відповіді, що стосуються лише коду, можуть вирішити проблему, але вони набагато корисніші, якщо ви поясните, як вони її вирішують. Спільнота вимагає теорії, а також коду, щоб повністю зрозуміти вашу відповідь.
RBT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.