我正在编写一个服务,将特定类型的对象集合转换为字符串,并输出其原始、字符串和日期时间类型,格式为CSV格式。我已经使以下两个语句都能正常工作。我发现基于lambda的版本更加简洁。
我随后将
魔法字符串版本
string csv = new ToCsvService<DateTime>(objs)
.Exclude("Minute")
.ChangeName("Millisecond", "Milli")
.Format("Date", "d")
.ToCsv();
vs. 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)
我随后将
expression.Body
传递给 FindMemberExpression
。我改编了 ExpressionProcessor.cs 中的 FindMemberExpression
方法的代码,该方法来自于 nhlambdaextensions项目。下面是我非常相似的版本的 FindMemberExpression
: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
中的足够案例吗?考虑到我的使用情况,我所做的是否过度了?
{p => Convert(p.Minute)}
,其中expression.Body
是{Convert(p.Minute)}
,它是一个UnaryExpression
。因此,我取出了Operand
,即p.Minute
,一个MemberExpression
,从那里我可以获取Member.Name
。最终,从我的视角来看,我正在采取p => p.Minute
并将其沿着这个方式运行((expression.Body as UnaryExpression).Operand as MemberExpression).Member.Name
。你是说有一种更“简洁”的方法来做到这一点,还是我完全没有理解你的意思? - ahsteele