c# - Using a lambda expression to avoid using a "magic string" to specify a property -
i writing service take collection of objects of particular type , output primitive, string, , datetime types string in csv format. have both of below statements working. find the lambda based version cleaner.
magic string version
string csv = new tocsvservice<datetime>(objs) .exclude("minute") .changename("millisecond", "milli") .format("date", "d") .tocsv();
vs. lambda version
string csv = new tocsvservice<datetime>(objs) .exclude(p => p.minute) .changename(p => p.millisecond, "milli") .format(p => p.date, "d") .tocsv();
per jon skeet's recommendation of lambda methods share similar method signature
public itocsvservice<t> exclude<tresult>( expression<func<t, tresult>> expression)
i pass expression.body
findmemberexpression
. i've adapted code findmemberexpression
method of expressionprocessor.cs nhlambdaextensions project. similar version of findmemberexpression
below:
private string findmemberexpression(expression expression) { if (expression memberexpression) { memberexpression memberexpression = (memberexpression)expression; if (memberexpression.expression.nodetype == expressiontype.memberaccess || memberexpression.expression.nodetype == expressiontype.call) { if (memberexpression.member.declaringtype.isgenerictype && memberexpression.member.declaringtype .getgenerictypedefinition().equals(typeof(nullable<>))) { if ("value".equals(memberexpression.member.name)) { return findmemberexpression(memberexpression.expression); } return string.format("{0}.{1}", findmemberexpression(memberexpression.expression), memberexpression.member.name); } } else { return memberexpression.member.name; } } throw new exception("could not determine member " + expression.tostring()); }
i testing enough cases in findmemberexpression
? doing overkill given use case?
edit: core making simpler change signature of methods generic in result type too:
public itocsvservice<tsource> exclude<tresult>( expression<func<tsource, tresult>> expression)
that way won't end conversion expression because no conversion necessary. example, p => p.minute
end expression<func<datetime, int>>
automatically due type inference.
it looks overkill me, given @ moment need property - @ least, that's sample shows.
why not start off recognising property, , expand later if need to?
edit: here's short complete example doesn't show conversions:
using system; using system.linq.expressions; class test { static void main() { expression<func<datetime, int>> dt = p => p.minute; console.writeline(dt); } }
if change expression type expression<func<datetime, long>>
however, does show convert(...)
bit. suspect need change signatures of exclude
(etc) methods.
Comments
Post a Comment