0
我想創建一個ExpressionVisitor以重新創建表達式作爲輸入字符串(有一些例外,如捕獲變量應顯示爲文本)。自定義ExpressionTree ToString
當我需要訪問表達式成員的表達式成員時,我被卡住了。我怎樣才能讓下面的:
public class Starter
{
private static void Main(string[] args)
{
var test = new SomeClass();
test.EchoTest();
Console.ReadLine();
}
}
public class SomeClass
{
public string StringMember { get; set; }
public SomeClass Other { get; set; }
public void EchoTest()
{
var capturedString = "localStringValue";
Echo((() => "hardcodedString"));//Ok :() => "hardcodedString"
Echo((() => capturedString));//Ok :() => "localStringValue" (I want the value in this case)
Echo((() => this.StringMember));//Ok :() => this.StringMember
Echo((() => this.Other.StringMember));//Failed, expected :() => this.Other.StringMember , received :() => this.Other.this.Other
}
private void Echo(Expression<Func<string>> expression)
{
Console.WriteLine(PathVisitor.GetPath(expression));
}
}
public class PathVisitor : ExpressionVisitor
{
private string _path;
protected override Expression VisitLambda<T>(Expression<T> node)
{
Visit(node.Body);
_path = string.Format("() => {0}", _path);
return node;
}
protected override Expression VisitConstant(ConstantExpression node)
{
_path = string.Format("\"{0}\"", node.Value);
return node;
}
protected override Expression VisitMember(MemberExpression node)
{
var generatedClass = null != Attribute.GetCustomAttribute(node.Expression.Type, typeof(CompilerGeneratedAttribute));
if (node.Expression.NodeType == ExpressionType.Constant && generatedClass)
{
var getter = Expression.Lambda(node); //let's eval captured Variable
_path = string.Format("\"{0}\"", getter.Compile().DynamicInvoke());
}
else if (node.Expression.NodeType == ExpressionType.Constant)
{
_path = string.Format("this.{0}", node.Member.Name);
}
else
{
base.Visit(node.Expression);
var callerPath = _path;
_path = string.Format("{0}.{1}", callerPath, _path);
}
return node;
}
public static string GetPath(Expression expression)
{
var visitor = new PathVisitor();
visitor.Visit(expression);
return visitor._path;
}
}