First impressions of Linq Expression<>

While at work yesterday, I saw a whole bunch of code like


if (memberid > 0)
  parameters.Add(new SqlParameter("@memberid", memberid));
if (groupid > 0)
  parameters.Add(new SqlParameter("@groupid", groupid));
if (industryid > 0)
  parameters.Add(new SqlParameter("@industryid", industryid));
...

and so on.

It would be easy enough to squeeze it down to something like


InsertIfGz("@memberid", memberid);
InsertIfGz("@groupid", groupid);
but it seemed a shame to have to specify both the parameter name and the variable.

I thought it would be nice to write a macro &emdash; which I can’t &emdash; but since I can look at expression trees of lambdas, I could do a similar thing at runtime;


// lambda that takes no args and returns a long
InsertIfGz( () = > memberid);
...
void InsertIfGz(Expression<Func<long>> f)
{
    // get the body of the function; args are nil, anyway
    var mx = (MemberExpression)f.Body;
    string name = mx.Member.Name;
    // compile the expr to a proper function, then call it
    long val = f.Compile()();
    // obviously this would be abstracted out & we might just
    // curry with (>0) for ease of use
    if (val > 0)
        parameters.Add("@"+name, val);
}

Anyway, I think it’s quite cute, but it’s not perfect: mainly because it still gets executed at run-time instead of compile-time. This means that if someone calls it with a bad argument, e.g. () => 5 + 2, then it will still compile but bomb out when we try to run it. That’s sad. I also imagine that if you were running that code in a tight loop it might affect speed a little, but that’s pure speculation.

Leave a Reply