簡體   English   中英

獲取功能 <T> 和表達 <Func<T> &gt;從單個參數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM