2015-12-01 53 views
1

我在表達式樹中做了一些工作。當您在一個表達式樹調用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() })); 
} 

它不編譯。爲什麼?我需要做些什麼來解決這個問題?

+0

它不會編譯,因爲該公司預計Expression's的'一個數組,但你給它一個字符串數組。你需要將它改成一個表達式,它在'Expression.Constant(exp)'上調用'ToString'' – Rob

回答

2

根據我的評論,它期望Expression[],但你已通過它string[]。你可以這樣做,這將立即運行ToString()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())是的ToString調用上exp,使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()) 
+0

顯然我對這個工作方式的一些假設是無效的,因爲我現在得到錯誤'二元運算符Or沒有爲類型'System.Void'和'System.Void'定義...但是我要標記這個完成,因爲它解決了手頭的問題。謝謝。 –

+0

@RobertHarvey很高興有幫助。至於你的其他錯誤,我可以假設你正在做'Expression.OrElse(WithLog(...),...)'嗎?如果*是*,那麼您需要更改'WithLog'方法中的塊以返回原始表達式。就目前而言,它正在編譯成諸如'(e)=> Print(exp)||之類的東西e.LastName =「Doe」' – Rob

+0

更像'WithLog(Expression.OrElse(blah))'。但是,是這樣的。你說得對;我想我需要返回原來的表達,而不是新的表達。我對錶達式樹很新穎。 –