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