{"id":4549,"date":"2017-01-08T20:09:12","date_gmt":"2017-01-08T20:09:12","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=4549"},"modified":"2017-01-08T20:09:12","modified_gmt":"2017-01-08T20:09:12","slug":"fun-with-expression-objects","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/fun-with-expression-objects\/","title":{"rendered":"Fun with Expression objects"},"content":{"rendered":"<p>Expressions are very useful in many situation. For example, you have a method which you pass a lambda expression to and the method can then determine the name of the property the lambda is using or the method name etc. Or maybe you&#8217;ve used them in the past in view model implementations pre-nameof. They&#8217;re also used a lot in mocking frameworks, to make the arrange steps nice and terse.<\/p>\n<p>For example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nExpressions.NameOf(x =&gt; x.Property);\r\n<\/pre>\n<p>In the above example the lambda expression is the x => x.Property and the NameOf method determines the name of the property, i.e. it returns the string &#8220;Property&#8221; in this case.<\/p>\n<p><em>Note: This example is a replacement for the nameof operator for pre C# 6 code bases.<\/em><\/p>\n<p>Let&#8217;s look at some implementations of such expression code.<\/p>\n<p><strong>InstanceOf<\/strong><\/p>\n<p>So you have code in the format<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nExpressions.InstanceOf(() =&gt; s.Clone());\r\n<\/pre>\n<p>In this example Expressions is a static class and InstanceOf should extract the instance <em>s<\/em> from the expression s.Clone(). Obviously we might also need to use the same code of a property, i.e. find the instance of the object with the property.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static object InstanceOf&lt;TRet&gt;(Expression&lt;Func&lt;TRet&gt;&gt; funcExpression)\r\n{\r\n   var method = funcExpression.Body as MethodCallExpression;\r\n   \/\/ if not a methood, try to get the body (possibly it's a property)\r\n   var memberExpression = method == null ? \r\n      funcExpression.Body as MemberExpression : \r\n      method.Object as MemberExpression;\r\n\r\n   if(memberExpression == null)\r\n      throw new Exception(&quot;Unable to determine expression type, expected () =&gt; vm.Property or () =&gt; vm.DoSomething()&quot;);\r\n\r\n   \/\/ find top level member expression\r\n   while (memberExpression.Expression is MemberExpression)\r\n      memberExpression = (MemberExpression)memberExpression.Expression;\r\n\r\n   var constantExpression = memberExpression.Expression as ConstantExpression;\r\n   if (constantExpression == null)\r\n      throw new Exception(&quot;Cannot determine constant expression&quot;);\r\n\r\n   var fieldInfo = memberExpression.Member as FieldInfo;\r\n   if (fieldInfo == null)\r\n      throw new Exception(&quot;Cannot determine fieldinfo object&quot;);\r\n\r\n   return fieldInfo.GetValue(constantExpression.Value);\r\n}\r\n<\/pre>\n<p><strong>NameOf<\/strong><\/p>\n<p>As this was mentioned earlier, let&#8217;s look at the code for a simple nameof replacement using Expressions. This implementation only works with properties<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static string NameOf&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; propertyExpression) \r\n{\r\n   if (propertyExpression == null)\r\n      throw new ArgumentNullException(&quot;propertyExpression&quot;);\r\n\r\n   MemberExpression property = null;\r\n\r\n   \/\/ it's possible to end up with conversions, as the expressions are trying \r\n   \/\/ to convert to the same underlying type\r\n   if (propertyExpression.Body.NodeType == ExpressionType.Convert)\r\n   {\r\n      var convert = propertyExpression.Body as UnaryExpression;\r\n      if (convert != null)\r\n      {\r\n         property = convert.Operand as MemberExpression;\r\n      }\r\n   }\r\n\r\n   if (property == null)\r\n   {\r\n      property = propertyExpression.Body as MemberExpression;\r\n   }\r\n   if (property == null)\r\n      throw new Exception(\r\n         &quot;propertyExpression cannot be null and should be passed in the format x =&gt; x.PropertyName&quot;);\r\n\r\n   return property.Member.Name;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Expressions are very useful in many situation. For example, you have a method which you pass a lambda expression to and the method can then determine the name of the property the lambda is using or the method name etc. Or maybe you&#8217;ve used them in the past in view model implementations pre-nameof. They&#8217;re also [&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,153],"tags":[],"class_list":["post-4549","post","type-post","status-publish","format-standard","hentry","category-c","category-expression"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4549","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=4549"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4549\/revisions"}],"predecessor-version":[{"id":4565,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4549\/revisions\/4565"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=4549"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=4549"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=4549"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}