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