Saturday, March 21, 2015

struggling to understand building a Func or an Action from C# expressions

If want to make a Func from this method...

namespace Expressy.Models
{
   public class MessageMaker
   {
      public string HugsAndKisses(int count, bool isToKissFirst)
      {
         int counter = 0;
         string hugsAndKisses = "";
         if (isToKissFirst)
         {
            while (counter < count)
            {
               hugsAndKisses += "XO";
               counter++;
            }
         } else {
            while (counter < count)
            {
               hugsAndKisses += "OX";
               counter++;
            }
         }
         return hugsAndKisses;
      }
   }
}

 
 

...not unlike so...

using System;
using System.Web.Mvc;
using Expressy.Models;
namespace Expressy.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         MessageMaker messageMaker = new MessageMaker();
         Func<int, bool, string> funky = messageMaker.HugsAndKisses;
         ViewBag.Message = funky(13, true);
         return View();
      }
   }
}

 
 

...yet with an expression. How may I do so? I've gotten this far...

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
using Expressy.Models;
namespace Expressy.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         var intType = Expression.Parameter(typeof(int), "int");
         var boolType = Expression.Parameter(typeof(bool), "bool");
         Type type = typeof (MessageMaker);
         var target = Expression.Parameter(type, "t");
         MethodInfo methodInfo = type.GetMethods()[0];
         Expression call = Expression.Call(target, methodInfo, intType, boolType);
         var lambda = Expression.Lambda<Func<int, bool, string>>(call, intType,
               boolType);
         Func<int, bool, string> func = lambda.Compile();
         ViewBag.Message = func(13, true);
         return View();
      }
   }
}

 
 

...and that surfaces this error:

variable 't' of type 'Expressy.Models.MessageMaker' referenced from scope '', but it is not defined

 
 

The hyperfast reflection implementation that a coworker has crafted uses expressions with stuff plucked from reflection to create Actions to do the setting of getsetters on POCOs. I hate to just plagiarizer his work on my blog so I thought I'd try to figure out how to do the expressions myself. I'm coming up sort. When I Google the error message it vaguely feels like I'm missing an expression for a "p" convention to go with my expression for "t" and it seems the "t" and "p" are commonly used when staging expressions in this manner. He, my colleague, does have something like so in his code...

var somethingMore = Expression.Parameter(typeof(object), "p");

 
 

...but I'm not sure how to jam it in myself. Maybe I'll follow up this blog posting with another or maybe I'll let this be. We shall see. I found this from some time ago which is easier to read honestly.

No comments:

Post a Comment