我想获得lambda Func<>的字符串表示形式表达式以获取属性路径。我有这个例子
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses["Address"];
我期待一个字符串
"EmployeeInfo.Addresses["Address"]"
当我 _xxx.ToString(); 我只是做一些字符串解析,我可以得到上面的结果。
我的问题是我什么时候
var _addrName = "Address";
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses[_addrName];
我有一个非常长的字符串
"EmployeeInfo.Addresses.get_Item(value(UnitTestProj.UnitTest.AnyTest+<>c__DisplayClass0)._addr)"
很难操纵起来 &#34; EmployeeInfo.Addresses [&#34;地址&#34;]&#34;
有没有办法达到我的目的?
TIA
答案 0 :(得分:3)
这应该会让你走得很远 - 这非常hacky但是我认为没有办法解决它:
Expression<Func<Employee, object>> _xxx = e => e.EmployeeInfo.Addresses[address];
WriteLine(ExprToString(_xxx)); //e.EmployeeInfo.Addresses[address]
_xxx = x => x.EmployeeInfo.Addresses["XYZ"];
WriteLine(ExprToString(_xxx)); //x.EmployeeInfo.Addresses["XYZ"]
_xxx = y => y.EmployeeInfo.Addresses[null];
WriteLine(ExprToString(_xxx)); //y.EmployeeInfo.Addresses[null]
_xxx = z => z.EmployeeInfo.Name;
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Name
_xxx = z => z.EmployeeInfo.GetSalary();
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.GetSalary()
_xxx = z => z.EmployeeInfo.Addresses.Select(a => a.Street);
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Addresses.Select(a.Street)
_xxx = z => z.EmployeeInfo.Array[3];
WriteLine(ExprToString(_xxx)); //z.EmployeeInfo.Array[3]
实施:
static string ExprToString(Expression expr)
{
switch (expr.NodeType)
{
case ExpressionType.Lambda:
//x => (Something), return only (Something), the Body
return ExprToString(((LambdaExpression) expr).Body);
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
//type casts are not important
return ExprToString(((UnaryExpression) expr).Operand);
case ExpressionType.Call:
//method call can be an Indexer (get_Item),
var callExpr = (MethodCallExpression) expr;
if (callExpr.Method.Name == "get_Item")
{
//indexer call
return ExprToString(callExpr.Object) + "[" + string.Join(",", callExpr.Arguments.Select(ExprToString)) + "]";
}
else
{
//method call
var arguments = callExpr.Arguments.Select(ExprToString).ToArray();
string target;
if (callExpr.Method.IsDefined(typeof (ExtensionAttribute), false))
{
//extension method
target = string.Join(".", arguments[0], callExpr.Method.Name);
arguments = arguments.Skip(1).ToArray();
}
else if (callExpr.Object == null)
{
//static method
target = callExpr.Method.Name;
}
else
{
//instance method
target = string.Join(".", ExprToString(callExpr.Object), callExpr.Method.Name);
}
return target + "(" + string.Join(",", arguments) + ")";
}
case ExpressionType.MemberAccess:
//property or field access
var memberExpr = (MemberExpression) expr;
if (memberExpr.Expression.Type.Name.Contains("<>")) //closure type, don't show it.
{
return memberExpr.Member.Name;
}
else
{
return string.Join(".", ExprToString(memberExpr.Expression), memberExpr.Member.Name);
}
}
//by default, show the standard implementation
return expr.ToString();
}