用记录器包装表达式树
Wrapping an Expression Tree with a Logger
我正在做一些表达式树方面的工作。当您在表达式树上调用 ToString() 时,您会得到一些可爱的诊断文本(这里是一个示例):
((Param_0.Customer.LastName == "Doe")
AndAlso ((Param_0.Customer.FirstName == "John")
Or (Param_0.Customer.FirstName == "Jane")))
所以我写了这段代码,试图用一些日志记录功能包装表达式:
public Expression WithLog(Expression exp)
{
return Expression.Block(exp, Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { exp } ));
}
我半预料到方法调用会推断 ToString() 的用法,但我想这是一个编译时功能。当我执行此操作时,出现错误:
Expression of type 'System.Boolean' cannot be used for parameter of type 'System.String' of method 'Void Print(System.String)
很公平。但是当我把它改成这个时:
public Expression WithLog(Expression exp)
{
return Expression.Block(exp, Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { exp.ToString() } ));
}
它不编译。为什么?我需要做什么来解决这个问题?
根据我的评论,预计 Expression[]
,但您已经通过 string[]
。你可以这样做,这将立即 运行 ToString()
on exp
:
public Expression WithLog(Expression exp)
{
return Expression.Block(Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { Expression.Constant(exp.ToString()) } ), exp);
}
产生:
Print("c => ((c.LastName == "Doe") AndAlso ((c.FirstName == "John") OrElse (c.LastName == "Jane")))")
或者,您可以将 Expression.Constant(exp.ToString())
更改为对 exp
的 ToString
调用,以便在调用表达式时执行 ToString
。
public Expression WithLog(Expression exp)
{
return Expression.Block(Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { Expression.Call(Expression.Constant(exp), exp.GetType().GetMethod("ToString")) } ), exp);
}
给出:
Print(c => ((c.LastName == "Doe") AndAlso ((c.FirstName == "John") OrElse (c.LastName == "Jane"))).ToString())
我正在做一些表达式树方面的工作。当您在表达式树上调用 ToString() 时,您会得到一些可爱的诊断文本(这里是一个示例):
((Param_0.Customer.LastName == "Doe")
AndAlso ((Param_0.Customer.FirstName == "John")
Or (Param_0.Customer.FirstName == "Jane")))
所以我写了这段代码,试图用一些日志记录功能包装表达式:
public Expression WithLog(Expression exp)
{
return Expression.Block(exp, Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { exp } ));
}
我半预料到方法调用会推断 ToString() 的用法,但我想这是一个编译时功能。当我执行此操作时,出现错误:
Expression of type 'System.Boolean' cannot be used for parameter of type 'System.String' of method 'Void Print(System.String)
很公平。但是当我把它改成这个时:
public Expression WithLog(Expression exp)
{
return Expression.Block(exp, Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { exp.ToString() } ));
}
它不编译。为什么?我需要做什么来解决这个问题?
根据我的评论,预计 Expression[]
,但您已经通过 string[]
。你可以这样做,这将立即 运行 ToString()
on exp
:
public Expression WithLog(Expression exp)
{
return Expression.Block(Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { Expression.Constant(exp.ToString()) } ), exp);
}
产生:
Print("c => ((c.LastName == "Doe") AndAlso ((c.FirstName == "John") OrElse (c.LastName == "Jane")))")
或者,您可以将 Expression.Constant(exp.ToString())
更改为对 exp
的 ToString
调用,以便在调用表达式时执行 ToString
。
public Expression WithLog(Expression exp)
{
return Expression.Block(Expression.Call(
typeof (Debug).GetMethod("Print",
new Type [] { typeof(string) }),
new [] { Expression.Call(Expression.Constant(exp), exp.GetType().GetMethod("ToString")) } ), exp);
}
给出:
Print(c => ((c.LastName == "Doe") AndAlso ((c.FirstName == "John") OrElse (c.LastName == "Jane"))).ToString())