277

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?

dkackman
  • 14,789
  • 11
  • 66
  • 120
Craig
  • 35,534
  • 33
  • 112
  • 193
  • possible duplicate of [How to set a property of a C# 4 dynamic object when you have the name in another variable](http://stackoverflow.com/questions/3033410/how-to-set-a-property-of-a-c-sharp-4-dynamic-object-when-you-have-the-name-in-an) – nawfal Jul 19 '14 at 15:55

4 Answers4

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

Alternatively:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);
Stephen Cleary
  • 406,130
  • 70
  • 637
  • 767
  • 38
    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 – Dynalon Jan 27 '12 at 18:48
  • It is amazing, and I have demonstrate that they are actually becoming properties of the object with sample code in my post on http://stackoverflow.com/questions/11888144/name-variable-using-string-net/11893463#11893463, thanks – yoel halb Aug 10 '12 at 02:42
  • 3
    getting `Error 53 Cannot convert type 'System.Dynamic.ExpandoObject' to 'System.Collections.Generic.IDictionary' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion` – TheVillageIdiot Oct 30 '12 at 09:23
  • 27
    It's `IDictionary`, not `IDictionary`. – Stephen Cleary Oct 30 '12 at 13:29
  • It might not be a good idea to cast to dictionary and add properties. https://connect.microsoft.com/VisualStudio/feedback/details/783541/expandoobjects-leak-memory-when-used-as-an-idictionary-string-object-to-add-new-properties – Marko Jan 16 '15 at 10:52
  • @Marko: That "leak" is only if you add many different property names, and would have the same exact behavior if you added the same property names via `dynamic`. – Stephen Cleary Jan 16 '15 at 14:27
  • May worth pointing out the first one doesn't work with `var x`. It only works with `dynamic x`. – Adam Szabo Sep 14 '15 at 10:44
  • That's beautiful, exactly what I wanted. – garryp Aug 17 '16 at 14:49
  • Kudos for providing 2 implementations – Leo Gurdian Mar 23 '17 at 00:13
  • 11
    It's important to note that when you're casting as `IDictionary` that you don't use `dynamic` as the variable type. – user3791372 May 14 '17 at 17:42
  • 1
    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 myExpando = new ExpandoObject();` – Abel Wenning Mar 11 '21 at 00:14
28

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();
Chris Marisic
  • 31,683
  • 22
  • 160
  • 255
Himanshu Patel
  • 646
  • 7
  • 12
21

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");
TECNO
  • 143
  • 1
  • 3
  • 14
Johannes
  • 511
  • 5
  • 6
0

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)
  • 7
    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. – RBT Mar 30 '20 at 00:57