2012-04-24 71 views
3

是否有更好的方法來實現它?我應該關心這裏的編譯方法的性能嗎?直接使用函數並作爲lambda表達式使用函數

 Public Overrides Function GetValidSerialNumbers() As System.Collections.Generic.IEnumerable(Of SerialNumber) 
     Return Queryable.Where(allSerials, SerialNumberValidFunc) 
    End Function 

    Public Overrides Function IsSerialNumberValid(serialNumber As SerialNumber) As Boolean 
     Return (SerialNumberValidFunc.Compile().Invoke(serialNumber)) 
    End Function 

    Private ReadOnly Property SerialNumberValidFunc As Expressions.Expression(Of Func(Of SerialNumber, Boolean)) 
     Get 
      If ProductionReceiptLine.MOOutput Is Nothing Then 
       Return Function(sn As SerialNumber) sn.ItemInventory Is Nothing AndAlso _ 
        (sn.Status = SerialNumberStatusValues.Planned AndAlso sn.MO Is ProductionReceiptLine.ProductionReceipt.MO _ 
        OrElse sn.Status = SerialNumberStatusValues.Assigned) 
      Else 
       Return Function(sn As SerialNumber) sn.ItemInventory Is Nothing AndAlso _ 
        (sn.Status = SerialNumberStatusValues.Planned AndAlso sn.MO Is Nothing OrElse sn.Status = SerialNumberStatusValues.Assigned) 
      End If 
     End Get 
    End Property 

我想lambda表達式的原因是因爲我想要的功能,能夠通過LINQ到SQL轉換爲SQL獲得的所有道路。我想要直接版本的原因是因爲我有其他代碼需要在提交更改之前驗證各個序列號。而且我擔心GetValidSerialNumbers.Contains(serialNumber)會執行更復雜而不是必需的查詢。

回答

0

編譯方法是很慢的,因爲它需要從表達IL發射。調用編譯後的函數將導致另一次編譯:JIT編譯。

我建議您緩存編譯的靜態場左右的結果。

你正在服用的一般方法是不錯的。它是乾的。

+0

與緩存的問題是,在這種形式下,緩存功能只會呼叫者對單個ProductionReceiptLine。但是,可能會重寫代碼以緩存接受ProductionReceiptLine作爲參數的函數版本,而不是將其硬編入Lambda表達式。最後,我決定減少DRY,因爲案件之間還有一些其他的區別。所以我簡單地複製了代碼。但很高興知道Compile和聽起來一樣昂貴。 – BlueMonkMN 2012-04-25 14:19:09

+0

現在我想到了,ProdutionLine和Me(aka this)將是函數的隱式參數(閉包?)嗎?函數的一個副本是否可以在共享(又名靜態)類成員上預編譯並提供所有實例?我沒有完全想到它,但那裏可能有些東西。 – BlueMonkMN 2012-04-26 10:56:28

相關問題