298

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?

1

4 Answers 4

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

Alternatively:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);
Sign up to request clarification or add additional context in comments.

11 Comments

I've never realized that Expando implements IDictionary<string, object>. 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>.
It's important to note that when you're casting as IDictionary that you don't use dynamic as the variable type.
If you implement as an IDictionary, then you don't have to cast it to use the methods from either the parent or derived class: IDictionary<string, object> myExpando = new ExpandoObject();
|
34

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

2 Comments

Your code is plain wrong, you skipped the most important part, which is the cast to a Dictionary.
@tocqueville, this answer is an enhancement to the current question and does not directly answer the question. The answer is an additional possibility. I hope you understand.
22

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

2 Comments

"var expandoDict = expando as IDictionary;" this line need to change to "var expandoDict = expando as IDictionary<String, object>;"
To make it even more awesome use those as extension methods.
3

This is the best solution I've found. But be careful with that. Use exception handling because it might not work on all of the cases

public static dynamic ToDynamic(this object obj)
{
    return JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));
}

//another nice extension method you might want to use

    public static T JsonClone<T>(this T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", nameof(source));
        }

        var serialized = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(serialized);
    }

3 Comments

Might not be as elegant as IDictionary, but only working solution if you later use this variable as dynamic (eg dynamic.Properties())
That's not useful if we are replacing Newtonsoft.Json with System.Text.Json…
Surprisingly, this solution works not only as alternative to IDictionary, but also created properties, which can be edited in PropertyGrid! Double + :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.