{"id":3013,"date":"2009-09-30T16:49:00","date_gmt":"2009-09-30T16:49:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2009\/09\/30\/dynamic-in-c-4-0-introducing-the-expandoobject\/"},"modified":"2019-02-14T15:42:20","modified_gmt":"2019-02-14T23:42:20","slug":"dynamic-in-c-4-0-introducing-the-expandoobject","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/dynamic-in-c-4-0-introducing-the-expandoobject\/","title":{"rendered":"Dynamic in C# 4.0: Introducing the ExpandoObject"},"content":{"rendered":"<p>You have probably already heard about the new dynamic feature in C# 4.0 and how it is used to support COM interop. If you haven&#8217;t, I strongly recommend reading the following MSDN articles: <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd264736(VS.100).aspx\">Using Type dynamic<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd264733(VS.100).aspx\">How to: Access Office Interop Objects by Using Visual C# 2010 Features<\/a>.<\/p>\n<p>Well, where else can you use this new feature? What are the use cases? Where does dynamic dispatch work better than static typing?<\/p>\n<p>The quick answer is that whenever you see syntax like <font face=\"Courier New\">myobject.GetProperty(&#8220;Address&#8221;)<\/font>, you have a use case for dynamic objects. First of all, the above syntax is difficult to read. Second, you don\u2019t have any IntelliSense support for the property name, and if the \u201cAddress\u201d property doesn\u2019t exist you get a run-time exception. So why not create a dynamic object that calls the property as <font face=\"Courier New\">myobject.Address<\/font>? You still get the run-time exception, and you still don&#8217;t get IntelliSense, but at least the syntax is much better.<\/p>\n<p>In fact, it<a title=\"OLE_LINK2\" name=\"OLE_LINK2\"><\/a><a title=\"OLE_LINK1\" name=\"OLE_LINK1\"><\/a>\u2019s not just better syntax. You also get flexibility. To demonstrate this flexibility, let\u2019s move to <font face=\"Courier New\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.dynamic.expandoobject(VS.100).aspx\">ExpandoObject<\/a><\/font>, which is a part of the new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233052(VS.100).aspx\">dynamic language runtime (DLR)<\/a>. <font face=\"Courier New\">ExpandoObject <\/font>instances can add and remove members at run time. Where can you use such an object? XML is a good candidate here.<\/p>\n<p>Here\u2019s a code example that I took from <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb387089.aspx\">MSDN<\/a>. (Yes, I am an MSDN writer myself, so I use MSDN a lot.)<\/p>\n<pre class=\"code\"><span>XElement <\/span>contactXML =\n    <span>new <\/span><span>XElement<\/span>(<span>\"Contact\"<\/span>,\n        <span>new <\/span><span>XElement<\/span>(<span>\"Name\"<\/span>, <span>\"Patrick Hines\"<\/span>),\n        <span>new <\/span><span>XElement<\/span>(<span>\"Phone\"<\/span>, <span>\"206-555-0144\"<\/span>),\n        <span>new <\/span><span>XElement<\/span>(<span>\"Address\"<\/span>,\n            <span>new <\/span><span>XElement<\/span>(<span>\"Street1\"<\/span>, <span>\"123 Main St\"<\/span>),\n            <span>new <\/span><span>XElement<\/span>(<span>\"City\"<\/span>, <span>\"Mercer Island\"<\/span>),\n            <span>new <\/span><span>XElement<\/span>(<span>\"State\"<\/span>, <span>\"WA\"<\/span>),\n            <span>new <\/span><span>XElement<\/span>(<span>\"Postal\"<\/span>, <span>\"68042\"<\/span>)\n        )\n    );<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Although LINQ to XML is a good technology and I really love it, those <span>new <\/span><span>XElement<\/span> parts look a little bit annoying. This is how I can rewrite it by using <font face=\"Courier New\">ExpandoObject<\/font>.<\/p>\n<pre class=\"code\"><span>dynamic <\/span>contact = <span>new <\/span><span>ExpandoObject<\/span>();\ncontact.Name = <span>\"Patrick Hines\"<\/span>;\ncontact.Phone = <span>\"206-555-0144\"<\/span>;\ncontact.Address = <span>new <\/span><span>ExpandoObject<\/span>();\ncontact.Address.Street = <span>\"123 Main St\"<\/span>;\ncontact.Address.City = <span>\"Mercer Island\"<\/span>;\ncontact.Address.State = <span>\"WA\"<\/span>;\ncontact.Address.Postal = <span>\"68402\"<\/span>;<\/pre>\n<p>Just note a couple of things. First, look at the declaration of <font face=\"Courier New\">contact<\/font>.<\/p>\n<p><span>dynamic <\/span>contact = <span>new <\/span><span>ExpandoObject<\/span>();<\/p>\n<p>I didn\u2019t write <span>ExpandoObject <\/span>contact = <span>new <\/span><span>ExpandoObject<\/span>(), because if I did <font face=\"Courier New\">contact<\/font> would be a statically-typed object of the <font face=\"Courier New\">ExpandoObject<\/font> type. And of course, statically-typed variables cannot add members at run time. So I used the new <font face=\"Courier New\">dynamic<\/font> keyword instead of a type declaration, and since <font face=\"Courier New\">ExpandoObject<\/font> supports dynamic operations, the code works.<\/p>\n<p>Second, notice that every time I needed a node to have subnodes, I simply created a new instance of <font face=\"Courier New\">ExpandoObject<\/font> as a member of the <font face=\"Courier New\">contact<\/font> object.<\/p>\n<p>It looks like the <font face=\"Courier New\">ExpandoObject<\/font> example has more code, but it\u2019s actually easier to read. You can clearly see what subnodes each node contains, and you don\u2019t need to deal with the parentheses and indentation. But the best part is how you can access the elements now.<\/p>\n<p>This is the code you need to print the State field in LINQ to XML. <\/p>\n<pre class=\"code\"><span>Console<\/span>.WriteLine((<span>string<\/span>)contactXML.Element(<span>\"Address\"<\/span>).Element(<span>\"State\"<\/span>));<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>And this is how it looks with <font face=\"Courier New\">ExpandoObject<\/font>.<\/p>\n<pre class=\"code\"><span>Console<\/span>.WriteLine(contact.Address.State);<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a>But what if you want to have several Contact nodes? Like in the following LINQ to XML example.<\/p>\n<pre class=\"code\"><span>XElement <\/span>contactsXML =\n    <span>new <\/span><span>XElement<\/span>(<span>\"Contacts\"<\/span>,\n        <span>new <\/span><span>XElement<\/span>(<span>\"Contact\"<\/span>,\n            <span>new <\/span><span>XElement<\/span>(<span>\"Name\"<\/span>, <span>\"Patrick Hines\"<\/span>),\n            <span>new <\/span><span>XElement<\/span>(<span>\"Phone\"<\/span>, <span>\"206-555-0144\"<\/span>)\n        ),\n        <span>new <\/span><span>XElement<\/span>(<span>\"Contact\"<\/span>,\n            <span>new <\/span><span>XElement<\/span>(<span>\"Name\"<\/span>, <span>\"Ellen Adams\"<\/span>),\n            <span>new <\/span><span>XElement<\/span>(<span>\"Phone\"<\/span>, <span>\"206-555-0155\"<\/span>)\n        )\n    );<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Just use a collection of dynamic objects. <\/p>\n<pre class=\"code\"><span>dynamic <\/span>contacts = <span>new <\/span><span>List<\/span>&lt;<span>dynamic<\/span>&gt;();\ncontacts.Add(<span>new <\/span><span>ExpandoObject<\/span>());\ncontacts[0].Name = <span>\"Patrick Hines\"<\/span>;\ncontacts[0].Phone = <span>\"206-555-0144\"<\/span>;\ncontacts.Add(<span>new <\/span><span>ExpandoObject<\/span>());\ncontacts[1].Name = <span>\"Ellen Adams\"<\/span>;\ncontacts[1].Phone = <span>\"206-555-0155\"<\/span>;<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Technically speaking, I could write <span>dynamic <\/span>contacts = <span>new <\/span><span>List<\/span>&lt;<span>ExpandoObject<\/span>&gt;() and the example would work. However, there are some situations where this could cause problems, because the actual type of the list elements should be <font face=\"Courier New\">dynamic<\/font> and not <font face=\"Courier New\">ExpandoObject<\/font>, and these are two different types. (Once again, references to the <font face=\"Courier New\">ExpandoObject<\/font> objects are statically-typed and do not support dynamic operations.)<\/p>\n<p>Now, if you want to find all the names in your contact list, just iterate over the collection. <\/p>\n<pre class=\"code\"><span>foreach <\/span>(<span>var <\/span>c <span>in <\/span>contacts)\n    <span>Console<\/span>.WriteLine(c.Name);<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Again, this syntax is better than LINQ to XML version. <\/p>\n<pre class=\"code\"><span>foreach <\/span>(<span>var <\/span>c <span>in <\/span>contactsXML.Descendants(<span>\"Name\"<\/span>))\n    <span>Console<\/span>.WriteLine((<span>string<\/span>)c);<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a>So far, so good. But one of the main advantages of LINQ to XML is, well, LINQ. How would you query dynamic objects? Although there is still a lot to be done in this particular area, you can query dynamic objects. For example, let\u2019s find all the phone numbers for the specified name.<\/p>\n<pre class=\"code\"><span>var <\/span>phones = <span>from <\/span>c <span>in <\/span>(contacts <span>as <\/span><span>List<\/span>&lt;<span>dynamic<\/span>&gt;)\n             <span>where <\/span>c.Name == <span>\"Patrick Hines\"\n             <\/span><span>select <\/span>c.Phone;<\/pre>\n<p>True, the cast here doesn\u2019t look like something strictly necessary. Certainly the compiler could have determined at run-time that <font face=\"Courier New\">contacts<\/font> is <span>List<\/span>&lt;<span>dynamic<\/span>&gt;. But as I said, there is still some work to be done in this area.<\/p>\n<p>Another thing to note is that this trick works only for the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb397919.aspx\">LINQ to Objects<\/a> provider. To use dynamic objects in LINQ to SQL or other LINQ providers, you need to modify the providers themselves, and that\u2019s a completely different story.<\/p>\n<p>However, even with the cast, syntax is still better than in a LINQ to XML query. <\/p>\n<pre class=\"code\"><span>var <\/span>phonesXML = <span>from <\/span>c <span>in <\/span>contactsXML.Elements(<span>\"Contact\"<\/span>)\n                <span>where <\/span>c.Element(<span>\"Name\"<\/span>).Value == <span>\"Patrick Hines\"\n                <\/span><span>select <\/span>c.Element(<span>\"Phone\"<\/span>).Value;<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a>Sure, there are some things that look better in LINQ to XML. For example, if you want to delete a phone number for all the contacts, you can write just one line of code in LINQ to XML.<\/p>\n<pre class=\"code\">contactsXML.Elements(<span>\"Contact\"<\/span>).Elements(<span>\"Phone\"<\/span>).Remove();<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Since C# doesn\u2019t have syntax for removing object members, you don\u2019t have an elegant solution here. But <font face=\"Courier New\">ExpandoObject<\/font> implements <span>IDictionary<\/span>&lt;<span>String<\/span>, <span>Object<\/span>&gt; to maintain its list of members, and you can delete a member by deleting a key-value pair. <\/p>\n<pre class=\"code\"><span>foreach <\/span>(<span>var <\/span>person <span>in <\/span>contacts)\n    ((<span>IDictionary<\/span>&lt;<span>String<\/span>, <span>Object<\/span>&gt;)person).Remove(<span>\"Phone\"<\/span>);<\/pre>\n<p>There are other useful methods in LINQ to XML like <font face=\"Courier New\">Save()<\/font> and <font face=\"Courier New\">Load()<\/font>. For <font face=\"Courier New\">ExpandoObject<\/font> you need to write such methods yourself, but probably only once. Here, casting to the <font face=\"Courier New\">IDictionary<\/font> interface can help as well.<\/p>\n<p>And although I\u2019ve been comparing LINQ to XML and <font face=\"Courier New\">ExpandoObject<\/font> in this post, these two approaches are not \u201crivals\u201d. You can convert <font face=\"Courier New\">ExpandoObject<\/font> to <font face=\"Courier New\">XElement<\/font> and vice versa. For example, this is what the <font face=\"Courier New\">ExpandoObject<\/font> to <font face=\"Courier New\">XElement<\/font> conversion might look like. <\/p>\n<pre class=\"code\"><span>private static <\/span><span>XElement <\/span>expandoToXML(<span>dynamic <\/span>node, <span>String <\/span>nodeName)\n{\n    <span>XElement <\/span>xmlNode = <span>new <\/span><span>XElement<\/span>(nodeName);\n    <span>foreach <\/span>(<span>var <\/span>property <span>in <\/span>(<span>IDictionary<\/span>&lt;<span>String<\/span>, <span>Object<\/span>&gt;)node)\n    {\n        <span>if <\/span>(property.Value.GetType() == <span>typeof<\/span>(<span>ExpandoObject<\/span>))\n            xmlNode.Add(expandoToXML(property.Value, property.Key));\n        <span>else\n            if <\/span>(property.Value.GetType() == <span>typeof<\/span>(<span>List<\/span>&lt;<span>dynamic<\/span>&gt;))\n                <span>foreach <\/span>(<span>var <\/span>element <span>in <\/span>(<span>List<\/span>&lt;<span>dynamic<\/span>&gt;)property.Value)\n                    xmlNode.Add(expandoToXML(element, property.Key));\n            <span>else\n                <\/span>xmlNode.Add(<span>new <\/span><span>XElement<\/span>(property.Key, property.Value));\n    }\n    <span>return <\/span>xmlNode;\n}<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>This little trick might help you access all the LINQ to XML functions when you need them but at the same time use more convenient syntax when creating and modifying XML trees.<\/p>\n<p>Of course, XML is not the only area where you can use <font face=\"Courier New\">ExpandoObject<\/font>. If you heavily use reflection or work a lot with script objects, you can simplify your code with <font face=\"Courier New\">ExpandoObject<\/font>. On the other hand, <font face=\"Courier New\">ExpandoObject<\/font> is not the only useful class that the DLR provides. The <font face=\"Courier New\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.dynamic.dynamicobject(VS.100).aspx\">DynamicObject<\/a><\/font> class, for example, enables you to take more control over dynamic operations and define what actually happens when you access a member or invoke a method. But that\u2019s a topic for another blog post.<\/p>\n<p>One more thing to note is that libraries that look up members by name might someday adopt the DLR and implement the <font face=\"Courier New\">IDynamicMetaObjectProvider<\/font> interface. (This interface actually provides all the \u201cmagic\u201d \u2013 or dynamic dispatch \u2013 for <font face=\"Courier New\">ExpandoObject<\/font> and the dynamic feature in general.) For example, if LINQ to XML implements this interface, you would be able to write <span>dynamic <\/span>contacts = <span>new <\/span>XmlElement() instead of <span>dynamic <\/span>contacts = <span>new <\/span>ExpandoObject() and perform the same operations that I have shown in the examples for the <font face=\"Courier New\">ExpandoObject<\/font> type.<\/p>\n<p>All the examples provided in this blog post work in <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=151799\">Visual Studio 2010 Beta 1<\/a>. If you have any comments or suggestions, you are welcome to post them here or contact the DLR team at <a href=\"http:\/\/www.codeplex.com\/dlr\">http:\/\/www.codeplex.com\/dlr<\/a>. You can also write an e-mail to the DLR team at <a href=\"mailto:dlr@microsoft.com\">dlr@microsoft.com<\/a>.<\/p>\n<p><strong>Update:<\/strong><\/p>\n<p>See how&nbsp;you can&nbsp;improve this example in my next post: <span class=\"entrylistheader\"><a id=\"bp___v___r___postlist___EntryItems_ctl01_PostTitle\" href=\"http:\/\/blogs.msdn.com\/csharpfaq\/archive\/2009\/10\/19\/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject.aspx\"><font color=\"#006bad\" size=\"2\" face=\"Times New Roman\">Dynamic in C# 4.0: Creating Wrappers with DynamicObject<\/font><\/a>.<\/span><\/p>\n<p><img decoding=\"async\" src=\"\" width=\"1\" height=\"1\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You have probably already heard about the new dynamic feature in C# 4.0 and how it is used to support COM interop. If you haven&#8217;t, I strongly recommend reading the following MSDN articles: Using Type dynamic and How to: Access Office Interop Objects by Using Visual C# 2010 Features. Well, where else can you use [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[3,1383,185,357,13],"class_list":["post-3013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-net-framework","tag-c","tag-node-js","tag-sql","tag-visual-studio-2010"],"acf":[],"blog_post_summary":"<p>You have probably already heard about the new dynamic feature in C# 4.0 and how it is used to support COM interop. If you haven&#8217;t, I strongly recommend reading the following MSDN articles: Using Type dynamic and How to: Access Office Interop Objects by Using Visual C# 2010 Features. Well, where else can you use [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/3013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=3013"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/3013\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=3013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=3013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=3013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}