c# – 使用lambda表达式来避免使用“魔术字符串”来指定属性
我正在编写一个服务,在
CSV Format中将特定类型的对象集合和
output its primitive,string,and DateTime types作为字符串.我有以下两个语句都可以正常工作.我发现基于lambda的版本更清洁.
魔术弦版 string csv = new ToCsvService<DateTime>(objs) .Exclude("Minute") .ChangeName("Millisecond","Milli") .Format("Date","d") .ToCsv(); 与Lambda版本 string csv = new ToCsvService<DateTime>(objs) .Exclude(p => p.Minute) .ChangeName(p => p.Millisecond,"Milli") .Format(p => p.Date,"d") .ToCsv(); 根据Jon Skeet的建议,所有lambda方法都共享一个类似的方法签名 public IToCsvService<T> Exclude<TResult>( Expression<Func<T,TResult>> expression) 然后我将表达式.Body传递给FindMemberExpression.我已经从nhlambdaextensions project改编了 private string FindMemberExpression(Expression expression) { if (expression is 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 from " + expression.ToString()); } 我在FindMemberExpression中测试了足够多的案例?鉴于我的用例,我正在做什么矫枉过正? 解决方法
编辑:使这个更简单的核心是将方法的签名更改为结果类型中的通用:
public IToCsvService<TSource> Exclude<TResult>( Expression<Func<TSource,TResult>> expression) 这样您就不会得到转换表达式,因为不需要转换.例如,p => p.Minute将以表达式< Func< DateTime,int>>结束.由于类型推断自动. 对我来说这看起来有点矫枉过正,因为目前您需要的只是一个属性 – 至少,这就是您的样本所展示的一切. 为什么不从识别属性开始,如果需要,可以在以后扩展它? 编辑:这是一个简短但完整的示例,不显示任何转换: using System; using System.Linq.Expressions; class Test { static void Main() { Expression<Func<DateTime,int>> dt = p => p.Minute; Console.WriteLine(dt); } } 如果将表达式类型更改为Expression< Func< DateTime,long>>但是,它确实显示了Convert(…)位.我怀疑您需要更改Exclude(etc)方法的签名. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |