![](/img/trans.png)
[英]How to get returned properties from Expression<Func<T, object[]>> parameter
[英]Get Func<T> and Expression<Func<T>> from single parameter?
我想使用一個參數同時獲取已編譯的Func(boolean)和Expression(Func(of boolean))。 我無意修改表達式樹。 完全采用表達式樹的唯一原因是,這樣我就可以打印出正在執行的代碼。
void Assert(Expression<Func<bool>> assertionExpression) {
if (!assertionExpression.Compile()())
{
throw new AssertFailedException(assertionExpression.ToString());
}
}
有什么合理的方法可以做到這一點嗎?
作為問題,在簡單的編譯器生成的表達式樹的情況下,是否總是將同一實例作為參數傳遞?
static Dictionary<Expression<Func<bool>>, Func<bool>> cache;
static void Assert(Expression<Func<bool>> assertionExpression) {
Func<bool> method = null;
if (!cache.TryGetValue(assertionExpression, out method)) {
cache.Add(assertionExpression, method = assertionExpression.Compile());
Console.WriteLine("cache insert");
}
else {
Console.WriteLine("cache hit");
}
if (!method())
{
throw new AssertFailedException(assertionExpression.ToString());
}
}
static void someCodeThatExecutesRegularly() {
Assert(()=>true);
}
public static void Main(string[] args, int argc)
{
someCodeThatExecutesRegularly();
someCodeThatExecutesRegularly();
someCodeThatExecutesRegularly();
}
輸出將是“緩存插入”,“緩存命中”,“緩存命中”還是“緩存插入”,“緩存插入”,“緩存插入”。
對於第一個問題,盡管表達式樹每次都會重新編譯,所以您可以將表達式樹編譯為可執行文件,因此必須對其進行緩存。
static void Assert(Expression<Func<bool>> assertionExpression) {
var func = assertionExpression.Compile(); // if you call func() it will execute the expression
}
對於第二個問題,每次都會是一個新的表達式樹,因此您將獲得“緩存插入”,“緩存插入”,“緩存插入”等。
為了使它與緩存一起工作並進行編譯,您可以在表達式上使用.ToString()來獲取函數的字符串表示形式,但是如果您有任何閉包,這可能會引起非常混亂的問題,因為字符串表示形式可能相同,但是封閉變量將有所不同,因此,如果執行此操作,請小心使用!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.