{"id":1408,"date":"2014-02-18T21:35:25","date_gmt":"2014-02-18T21:35:25","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=1408"},"modified":"2014-02-18T21:35:25","modified_gmt":"2014-02-18T21:35:25","slug":"dynamic-objects","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/dynamic-objects\/","title":{"rendered":"Dynamic Objects"},"content":{"rendered":"<p>The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.dynamic.idynamicmetaobjectprovider(v=vs.110).aspx\" title=\"IDynamicMetaObjectProvider\" target=\"_blank\">IDynamicMetaObjectProvider<\/a> interface represents an object that can be late bound. <\/p>\n<p>Microsoft supplies to implementations of this interface out of the box. <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.dynamic.dynamicobject(v=vs.110).aspx\" title=\"DynamicObject Class\" target=\"_blank\">DynamicObject<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.dynamic.expandoobject(v=vs.110).aspx\" title=\"ExpandoObject Class\" target=\"_blank\">ExpandoObject<\/a>.<\/p>\n<p><strong>DynamicObject<\/strong><\/p>\n<p>The DynamicObject is mean&#8217;t to be used as a base class for the user&#8217;s own dynamic object and hence has a protected constructor. The idea is that we can create our own dynamic object and handle any attempted access to member properties or methods etc. at runtime.<\/p>\n<p>For example here&#8217;s an implementation of a dynamic object which adds (at runtime) a method which takes no arguments and returns a string<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class MyObject : DynamicObject\r\n{\r\n   public override bool TryGetMember(\r\n            GetMemberBinder binder, out object result)\r\n   {\r\n      result = null;\r\n      if (binder.Name == &quot;GetName&quot;)\r\n      {\r\n         result = new Func&lt;string&gt;(() =&gt; &quot;Hello World&quot;);\r\n         return true;\r\n      }\r\n      return false;\r\n   }\r\n}\r\n<\/pre>\n<p>If we wanted to handle a property named GetName we&#8217;d simply return a string, not a function. The TryGetMember is used for methods with no arguments or get properties, when arguments are supplied to a method we should override TryInvokeMember.<\/p>\n<p><strong>ExpandoObject<\/strong><\/p>\n<p>Unlike DynamicObject an ExpandoObject can be instantiated and then we can add methods and properties to it via it&#8217;s IDictionary<string, object> interfaces.<\/p>\n<p>So for example, let&#8217;s create an ExpandoObject and add a new method<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\ndynamic d = new ExpandoObject();\r\n\r\n((IDictionary&lt;string, object&gt;)d).Add(&quot;GetName&quot;, new Func&lt;string&gt;(() =&gt; &quot;Hello World&quot;));\r\n\r\nConsole.WriteLine(d.GetName());\r\n<\/pre>\n<p>As you can see we must ofcourse declare our variable as <em>dynamic<\/em> otherwise the use of GetName will cause the compilation error <\/p>\n<p><em>System.Dynamic.ExpandoObject&#8217; does not contain a definition for &#8216;GetName&#8217; and no extension method &#8216;GetName&#8217; accepting a first argument of type &#8216;System.Dynamic.ExpandoObject&#8217; could be found (are you missing a using directive or an assembly reference?)<\/em><\/p>\n<p>We also need to cast the instance to <em>IDictionary&lt;string, object&gt;<\/em> as access to the Add method needs to go through an explicit interface.<\/p>\n<p>So as you see, we can add to the ExpandoObject at runtime, unlike a DynamicObject derived class where only the derived class would be able to add to the object at runtime (obviously assuming we don&#8217;t add methods to allow this ourselves).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The IDynamicMetaObjectProvider interface represents an object that can be late bound. Microsoft supplies to implementations of this interface out of the box. DynamicObject and ExpandoObject. DynamicObject The DynamicObject is mean&#8217;t to be used as a base class for the user&#8217;s own dynamic object and hence has a protected constructor. The idea is that we can [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1408","post","type-post","status-publish","format-standard","hentry","category-c"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/1408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=1408"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/1408\/revisions"}],"predecessor-version":[{"id":1470,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/1408\/revisions\/1470"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=1408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=1408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=1408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}