2012-04-24 69 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

相关问题