By Reed Copsey


2009-10-31 01:09:42 8 Comments

The ExpandoObject class being added to .NET 4 allows you to arbitrarily set properties onto an object at runtime.

Are there any advantages to this over using a Dictionary<string,object>, or really even a Hashtable? As far as I can tell, this is nothing but a hash table that you can access with slightly more succinct syntax.

For example, why is this:

dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);

Really better, or substantially different, than:

var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);

What real advantages are gained by using ExpandoObject instead of just using an arbitrary dictionary type, other than not being obvious that you're using a type that's going to be determined at runtime.

10 comments

@Eng. M.Hamdy 2017-12-22 00:21:28

After valueTuples, what's the use of ExpandoObject class? this 6 lines code with ExpandoObject:

dynamic T = new ExpandoObject();
T.x = 1;
T.y = 2;
T.z = new ExpandoObject();
T.z.a = 3;
T.b= 4;

can be written in one line with tuples:

var T = (x: 1, y: 2, z: (a: 3, b: 4));

besides with tuple syntax you have strong type inference and intlisense support

@LxL 2018-02-08 00:15:09

Your examples are not identical in the sense that with value tuple, you cannot write T.c= 5; after finishing define T. With ExpandoObject you can do it because it's dynamic. Your example with value tuple is very identical with declaring anonymous type. E.g: var T2 = new { x = 1, y = 2, z = new { a = 3, b = 4 } };

@Eng. M.Hamdy 2018-02-09 02:55:17

Why do I need to write T.c= 5 without defining it? ExpandoObject is only usefull when dealing with COM objects that are not defiend in .net. Otherwise, I neever use this ExpandoObject, because it is dirty and buggy in both design time and runtime.

@LxL 2018-02-09 08:11:41

How about you have z at first assigned to (a:3,b:4) and then later you would like z to have additional c property? Can you do it with value tuple?

@LxL 2018-02-09 08:16:59

So my point is that you cannot compare ExpandoObject with value tuple because they are designed for different purposes. By comparing your way, you dismissed the functionality which ExpandoObject is designed for, which is dynamic structure.

@sgnsajgon 2014-11-26 16:10:58

It's example from great MSDN article about using ExpandoObject for creating dynamic ad-hoc types for incoming structured data (i.e XML, Json).

We can also assign delegate to ExpandoObject's dynamic property:

dynamic person = new ExpandoObject();
person.FirstName = "Dino";
person.LastName = "Esposito";

person.GetFullName = (Func<String>)(() => { 
  return String.Format("{0}, {1}", 
    person.LastName, person.FirstName); 
});

var name = person.GetFullName();
Console.WriteLine(name);

Thus it allows us to inject some logic into dynamic object at runtime. Therefore, together with lambda expressions, closures, dynamic keyword and DynamicObject class, we can introduce some elements of functional programming into our C# code, which we knows from dynamic languages as like JavaScript or PHP.

@alan2here 2016-02-05 17:59:22

var obj = new Dictionary<string, object>;
...
Console.WriteLine(obj["MyString"]);

I think that only works because everything has a ToString(), otherwise you'd have to know the type that it was and cast the 'object' to that type.


Some of these are useful more often than others, I'm trying to be thorough.

  1. It may be far more natural to access a collection, in this case what is effectively a "dictionary", using the more direct dot notation.

  2. It seems as if this could be used as a really nice Tuple. You can still call your members "Item1", "Item2" etc... but now you don't have to, it's also mutable, unlike a Tuple. This does have the huge drawback of lack of intellisense support.

  3. You may be uncomfortable with "member names as strings", as is the feel with the dictionary, you may feel it is too like "executing strings", and it may lead to naming conventions getting coded in, and dealing with working with morphemes and syllables when code is trying understand how to use members :-P

  4. Can you assign a value to an ExpandoObject itself or just it's members? Compare and contrast with dynamic/dynamic[], use whichever best suits your needs.

  5. I don't think dynamic/dynamic[] works in a foreach loop, you have to use var, but possibly you can use ExpandoObject.

  6. You cannot use dynamic as a data member in a class, perhaps because it's at least sort of like a keyword, hopefully you can with ExpandoObject.

  7. I expect it "is" an ExpandoObject, might be useful to label very generic things apart, with code that differentiates based on types where there is lots of dynamic stuff being used.


Be nice if you could drill down multiple levels at once.

var e = new ExpandoObject();
e.position.x = 5;
etc...

Thats not the best possible example, imagine elegant uses as appropriate in your own projects.

It's a shame you cannot have code build some of these and push the results to intellisense. I'm not sure how this would work though.

Be nice if they could have a value as well as members.

var fifteen = new ExpandoObject();
fifteen = 15;
fifteen.tens = 1;
fifteen.units = 5;
fifteen.ToString() = "fifteen";
etc...

@n1LWeb 2013-04-10 07:34:30

There are some cases where this is handy. I'll use it for a Modularized shell for instance. Each module defines it's own Configuration Dialog databinded to it's settings. I provide it with an ExpandoObject as it's Datacontext and save the values in my configuration Storage. This way the Configuration Dialog writer just has to Bind to a Value and it's automatically created and saved. (And provided to the module for using these settings of course)

It' simply easier to use than an Dictionary. But everyone should be aware that internally it is just a Dictionary.

It's like LINQ just syntactic sugar, but it makes things easier sometimes.

So to answer your question directly: It's easier to write and easier to read. But technically it essentially is a Dictionary<string,object> (You can even cast it into one to list the values).

@Drew Marsh 2009-10-31 01:19:17

Interop with other languages founded on the DLR is #1 reason I can think of. You can't pass them a Dictionary<string, object> as it's not an IDynamicMetaObjectProvider. Another added benefit is that it implements INotifyPropertyChanged which means in the databinding world of WPF it also has added benefits beyond what Dictionary<K,V> can provide you.

@bjull 2011-07-01 11:51:40

The real benefit for me is the totally effortless data binding from XAML:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

 <TextBlock Text="{Binding SomeData.WhatEver}" />

@Alexandra Rusina 2009-11-02 19:06:58

Since I wrote the MSDN article you are referring to, I guess I have to answer this one.

First, I anticipated this question and that's why I wrote a blog post that shows a more or less real use case for ExpandoObject: Dynamic in C# 4.0: Introducing the ExpandoObject.

Shortly, ExpandoObject can help you create complex hierarchical objects. For example, imagine that you have a dictionary within a dictionary:

Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] = "WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

The deeper is the hierarchy, the uglier is the code. With ExpandoObject it stays elegant and readable.

dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);

Second, as it was already pointed out, ExpandoObject implements INotifyPropertyChanged interface which gives you more control over properties than a dictionary.

Finally, you can add events to ExpandoObject like here:

class Program
{

   static void Main(string[] args)
   {
       dynamic d = new ExpandoObject();

       // Initialize the event to null (meaning no handlers)
       d.MyEvent = null;

       // Add some handlers
       d.MyEvent += new EventHandler(OnMyEvent);
       d.MyEvent += new EventHandler(OnMyEvent2);

       // Fire the event
       EventHandler e = d.MyEvent;

       if (e != null)
       {
           e(d, new EventArgs());
       }

       // We could also fire it with...
       //      d.MyEvent(d, new EventArgs());

       // ...if we knew for sure that the event is non-null.
   }

   static void OnMyEvent(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent fired by: {0}", sender);
   }

   static void OnMyEvent2(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
   }
}

@Reed Copsey 2009-11-02 19:11:18

Interesting. Thanks for the info re: events. That was a new one for me.

@Alexandra Rusina 2009-11-02 19:16:53

@ Reed Yes, events are not yet documented for ExpandoObject. This particular example actually came up in the discussion on the blog. I will probably add it to documentation later.

@Shimmy 2012-02-06 22:49:32

@AlexandraRusina, how does it know it's an event when you say d.MyEvent = null;, Or it doesn't?

@Jalal 2012-06-30 05:19:44

@Shimmy i think it's just a place holder for events or any type of property.

@Sergey Berezovskiy 2012-12-23 22:08:06

Maybe I'm missing something, but this is not event - this is a simple property of delegate type.

@Eris 2013-07-08 16:46:08

I believe it should be MyDelegate and not MyEvent.

@supercat 2013-08-21 20:05:54

The ExpandoObject used with dynamic looks pretty much like the VB.NET "!" syntax for properties with a string-type indexer, aside from using "." rather than "!" (in vb.net, Foo!Biz!Baz.St is equivalent to Foo["Biz"]["Baz"].St); for some applications I took to using the VB style back before Expando-Object existed (I use a dot rather than !` on the last layer to allow it to be strongly typed). What differences do you see between dynamic+Expando-Object and the VB style "!"?

@nawfal 2013-10-21 10:52:23

The first block can be written using anonymous types: var expando = new { Address = new { State = "WA" } }; Console.WriteLine(expando.Address.State); I find this more readable but ymmv. And given it's statically typed, it's more useful in this context.

@Dr Blowhard 2014-11-11 12:07:19

@nawfal thats not right - an anonymous is different to an Expando. You are creating an anonymous type, which can't then add arbitrary properties to.

@nawfal 2014-11-11 13:24:25

@SeanMill yes you're right about it. I just mean that "the given example" by the answerer can be better done using anonymous types. That is if all the properties are statically known. If you want to add properties dynamically, then you've to go the dictionary route again.

@Daniel Möller 2017-03-10 13:19:25

That's the javascript way of living :)

@NetMage 2018-01-12 20:30:26

Why not do a Dictionary<string,dynamic> instead of ExpandoObject for the root object, so the code for nested properties becomes just as easy: Console.WriteLine(dict["Address"]["State"]); ?

@gn22 2009-10-31 01:19:57

I think it will have a syntactic benefit, since you'll no longer be "faking" dynamically added properties by using a dictionary.

That, and interop with dynamic languages I would think.

@itowlson 2009-10-31 01:17:31

One advantage is for binding scenarios. Data grids and property grids will pick up the dynamic properties via the TypeDescriptor system. In addition, WPF data binding will understand dynamic properties, so WPF controls can bind to an ExpandoObject more readily than a dictionary.

Interoperability with dynamic languages, which will be expecting DLR properties rather than dictionary entries, may also be a consideration in some scenarios.

@surfmuggle 2013-03-05 21:04:02

It seems that databinding to dynamic objects is broken. The reporting user eisenbergeffect is here on SO and coordinator of caliburn.micro. @AlexandraRusina can you comment on the state of the bug and the status "Won't fix"

@Graham Bass 2015-12-04 08:17:21

For those curious, I am currently able to bind to List<dynamic> and IEnumerable<dynamic> using WPF4

@ChaosPandion 2009-10-31 01:15:46

It's all about programmer convenience. I can imagine writing quick and dirty programs with this object.

@Phil 2011-03-10 21:43:38

@J. Hendrix, do not forget that he also said "dirty". Intellisense has its downside, however, it makes debuggging and bug-catching easier. I personally still prefer static over dynamic types unless I am deal with a weird (and always rare) case.

@nawfal 2013-10-21 10:49:05

+1 for convenience. However I find anonymous types can be equally convenient as a simple property bag and just better for its static-ness.

@Tobias 2014-02-03 18:21:16

I would not want to use it in production code, but it is very convenient in test-code and can make it look very beautiful.

Related Questions

Sponsored Content

9 Answered Questions

[SOLVED] What are the correct version numbers for C#?

24 Answered Questions

11 Answered Questions

[SOLVED] What does the [Flags] Enum Attribute mean in C#?

  • 2008-08-12 04:09:16
  • Brian Leahy
  • 392360 View
  • 1181 Score
  • 11 Answer
  • Tags:   c# enums flags

56 Answered Questions

[SOLVED] What is the difference between String and string in C#?

16 Answered Questions

[SOLVED] What do two question marks together mean in C#?

29 Answered Questions

[SOLVED] What is the difference between const and readonly?

25 Answered Questions

[SOLVED] What is the best way to iterate over a dictionary?

  • 2008-09-26 18:20:06
  • Jake Stewart
  • 1227099 View
  • 2065 Score
  • 25 Answer
  • Tags:   c# dictionary loops

17 Answered Questions

33 Answered Questions

[SOLVED] What is a NullReferenceException, and how do I fix it?

Sponsored Content