ChatGPT解决这个技术问题 Extra ChatGPT

Dynamically adding properties to an ExpandoObject

I would like to dynamically add properties to a ExpandoObject at runtime. So for example to add a string property call NewProp I would like to write something like

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

Is this easily possible?


S
Stephen Cleary
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;

Alternatively:

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

I've never realized that Expando implements IDictionary. I've always thought that cast would copy it to a dictionary. However, your post made me understand that if you change the Dictionary, you also change the underlying ExpandoObject! Thanks a lot
getting 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
It's IDictionary<string, object>, not IDictionary<string, string>.
May worth pointing out the first one doesn't work with var x. It only works with dynamic x.
It's important to note that when you're casting as IDictionary that you don't use dynamic as the variable type.
C
Chris Marisic

As explained here by Filip - http://www.filipekberg.se/2011/10/02/adding-properties-and-methods-to-an-expandoobject-dynamicly/

You can add a method too at runtime.

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("Shout", new Action(() => { Console.WriteLine("Hellooo!!!"); }));
x.Shout();

Your code is plain wrong, you skipped the most important part, which is the cast to a Dictionary.
T
TECNO

Here is a sample helper class which converts an Object and returns an Expando with all public properties of the given object.

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<String, object>;
            if (expandoDict.ContainsKey(propertyName))
                expandoDict[propertyName] = propertyValue;
            else
                expandoDict.Add(propertyName, propertyValue);
        }
    }

Usage:

//Create Dynamic Object
dynamic expandoObj= dynamicHelper.convertToExpando(myObject);
    
//Add Custom Properties
dynamicHelper.AddProperty(expandoObj, "dynamicKey", "Some Value");

"var expandoDict = expando as IDictionary;" this line need to change to "var expandoDict = expando as IDictionary;"
To make it even more awesome use those as extension methods.
M
Morteza ebrahim nejad

i think this add new property in desired type without having to set a primitive value, like when property defined in class definition

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

Hey Morteza ! Code-only answers may solve the problem but they are much more useful if you explain how they solve it. Community requires theory as well as code both to understand your answer fully.