【问题标题】:Working around no lambdas in VS 2005在 VS 2005 中不使用 lambda
【发布时间】:2015-05-05 17:32:51
【问题描述】:

我从一些精彩的遗留代码中摘录了以下内容:

Private Sub SomeMethod()
    Dim deductibles As List(Of Integer) = GetDeductibles()    
    deductibles.RemoveAll(AddressOf LessThanMinDed)
EndSub
Private Function LessThanMinDed(ByVal i As Integer) As Boolean
    Return i < MinimumDeductible()
End Function

如果你是语言势利小人,我们可以这样写:

private void SomeMethod() {
    List<int> deductibles = GetDeductibles();    
    deductibles.RemoveAll(LessThanMinDed);
}
private bool LessThanMinDed(int i) {
    return i < MinimumDeductible();
}

MinimumDeductible() 进行数据库调用。有没有办法编写这个而不写像x = MinimumDeductible() : RemoveAll(Function(i) i &lt; x)(因为lambdas不在这个版本的VB.NET中)只会调用数据库一次?

已解决(某种):

像这样解决:

Public Class Foo
    Private CachedMinimum As Integer
    Private Sub SomeMethod()
        Dim deductibles As List(Of Integer) = GetDeductibles()
        Me.CachedMinimum = MinimumDeductible()
        deductibles.RemoveAll(AddressOf LessThanMinDed)
    End Sub
    Private Function LessThanMinDed(ByVal i As Integer) As Boolean
        Return i < CachedMinimum
    End Function
End Class

【问题讨论】:

  • 顺便说一句,我强烈建议您尝试迁移到更新版本的 VS。如果你真的必须从 VS2013 或 VS2015 开始,你仍然可以以 .NET 2.0 为目标......但你可以使用许多更新的语言功能。
  • @JonSkeet,我希望我能够做出这些决定……相信我,我会的。
  • 每个 lambda 表达式都可以用一些 For 循环和条件编写,因此请使用可用的 .net 框架中的可用函数编写您自己的函数

标签: .net vb.net lambda


【解决方案1】:

答案真的取决于语言。在 C# 2 中,我们没有 lambda 表达式,但我们确实有匿名方法......所以你可以这样写:

List<int> deductibles = GetDeductibles();    
deductibles.RemoveAll(delegate(int i) { return i < MinimumDeductible(); });

据我所知,VS 2005 附带的 VB 版本中没有对应的版本。

【讨论】:

    【解决方案2】:

    在一天结束时,Lambdas 只是语法糖。它们总是被转换成命名函数,所以是的,这肯定是可能的(你总是可以使用以下模式的改编来删除任何 lambda)。只需使用您需要的方法和要关闭的值的字段创建一个新对象:

    public class MyComparer
    {
        private int value;
        public MyComparer(int value)
        {
            this.value = value;
        }
        public bool LessThanMinDed(int i)
        {
            return i < value;
        }
    }
    

    你现在可以写了:

    var comparer = new MyComparer(MinimumDeductible())
    deductibles.RemoveAll(comparer.LessThanMinDed);
    

    【讨论】:

      【解决方案3】:

      “VS 2005”中没有 lambda 是什么意思(大概是 C# 2.0)?只是语法不同!

      int min = MinimumDeductible();
      
      deductibles.RemoveAll(delegate (int i) {
          return i < min;
      });
      

      【讨论】:

      • 这不是 lambda,它是一个匿名方法。
      • 那些不是 lambda 表达式——它们是匿名方法。是的,它们都是“内联”创建委托的两种方式,但是如果您在 C# 2 规范中查找“lambda”,您将找不到它。
      • @JonSkeet “lambda 函数”一词也存在于 C# 规范之外,无论你怎么看它都是 lambda 函数。
      • 当您使用特定技术时,我认为坚持使用该技术的术语是有意义的。术语“lambda 表达式”在 C# 中具有非常特殊的含义——并且 OP 明确打算使用它——所以我认为通过将它用于不同的东西来混淆水域是一个坏主意。如果你说的是“闭包”,那就另当别论了。
      • @MattiVirkkunen,很好的答案,但不幸的是代码是用 VB.NET 编写的,所以我无法使用它。
      【解决方案4】:

      1) 我会尝试在数据库上解决它。正如您所说,MinimumDeductible 来自数据库,我猜 GetDeductibles(..) 也可能来自同一个数据库,然后我会简单地创建一个类似的 SQL 视图

      SELECT * FROM Deductibles ApplicationSettings 
      WHERE Deductibles.Amount >= ApplicationSettings.MinimumDeductible;
      

      并在应用程序中选择已过滤的视图。

      2) 如果这不可能,我不会使用任何删除操作来解决问题。如果您在列表上使用删除,则必须首先找到该项目,这意味着如果您有 10,000 个项目,则必须平均比较 5000 行,直到找到该项目(因为列表不支持哈希码)。最好在一个循环中复制项目并将结果重新分配给前一个变量,如下所示:

          Private Sub SomeMethod()
              Dim deductibles As List(Of Integer) = GetDeductibles()
              Dim minimum As Int32 = MinimumDeductible()
              deductibles = GetFilteredDeductibles(deductibles, minimum)
          End Sub
      
          Private Shared Function GetFilteredDeductibles(rawDeductibles As List(Of Int32), minimumValue As Int32) As List(Of Int32)
              Dim result As New List(Of Int32)(rawDeductibles.Count)
              For Each myValue As Int32 In rawDeductibles
                  If (myValue >= minimumValue) Then
                      result.Add(myValue)
                  End If
              Next
              result.TrimExcess()
              Return result
          End Function
      

      【讨论】:

      • 感谢您的建议。这只是一个最多大约 10 个项目的列表,所以它在循环中迭代并不重要。但是,当有十次调用数据库时,它可能会变得昂贵。我只是将更改保留在客户端(我所做的),因为使用我们的系统进行更改会更容易一些。
      猜你喜欢
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多