繁体   English   中英

我可以使用方法代替带有额外参数的Lambda表达式吗

[英]Can I use a Method instead of Lambda expression with extra parameters

我有一个内联lambda表达式,希望在整个应用程序中使用。 我似乎找不到关于如何使用比被测元素更多的参数来执行此操作的参考。 这是我目前拥有的简单示例。

Private Sub Test()
    Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
    Dim Search As String = "*Jo*"
    Dim Result = List.Where(Function(Name) Name Like Search)
End Sub

我知道IEnumerable.Where接受元素类型为参数并返回布尔值的方法。

Private Sub Test()
    Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
    Dim Search As String = "*Jo*"
    Dim Result = List.Where(AddressOf FindName)
End Sub

Private Function FindName(Name As String) As Boolean
    Return Name Like "*Jo*"
End Function

我也想将Search变量传递给FindName。 我只是似乎无法弄清楚语法来完成此任务。 我想出的唯一可行的解​​决方案是将所有内容传递给函数以执行原始语句。

Private Sub Test()
    Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
    Dim Search As String = "*Jo*"
    Dim Result = FindName(List, Search)
End Sub

Private Function FindName(List As IEnumerable(Of String), Search As String) As IEnumerable(Of String)
    Return List.Where(Function(Name) Name Like Search)
End Function

不要觉得有义务在VB中回答。

lambda表达式的好处是,它们允许闭包自动捕获作用域本地的变量。 例如(原谅C#):

List.Where(i => FindName(i, Search));

在上面的代码中, Search变量实际上被封装在一个Closure中 如果只想传递一个方法,则必须模拟闭包对实际类结构的作用:

public class NameFinder
{
    private string _search;
    public NameFinder(string search) {
        _search = search;
    }
    public bool Match(string item) {
        // C# equivalent of "return item LIKE _search"
    }
}

// Usage
var nameFinder = new NameFinder(Search);
List.Where(nameFinder.Match);

但是,此策略仅在少数情况下有用。 我发现通常最好只使用一个lambda表达式,该表达式将适当的变量传递到执行所有工作的函数中。

我会使用扩展方法:-

Module Module1

    Sub main()
        Dim List As New List(Of String) From {"Joe", "Ken", "Bob", "John"}
        Dim Search As String = "*Jo*"
        Dim Result = List.FindName(Search)
    End Sub


End Module

Public Module Extensions

    <System.Runtime.CompilerServices.Extension()>
    Public Function FindName(List As IEnumerable(Of String), Search As String) As IEnumerable(Of String)

        Return List.Where(Function(Name) Name Like Search)

    End Function

End Module

您甚至可以使用Func(Of T,TResult)委托使用多个参数:

Dim names = {"Joe", "Ken", "Bob", "John", "Otto"}
Dim matchesPattern As Func(Of String, String, Boolean) =
    Function(input, searchPattern) input Like searchPattern
Dim results = names.Where(Function(name) matchesPattern(name, "?o*"))
' returns "Joe", "Bob" and "John" '

我认为您不能将更多参数传递给Where方法,但是您可以将搜索参数设置为FindName方法可以访问的类成员。 例如(我将用C#编写它,因为这是我更熟悉的东西):

string search = "Ken";

private void Test()
{
    var list = new List<string>() { "Joe", "Ken", "Bob", "John" };
    // Set search member to whatever you need before calling query
    search = "Joe";
    var result = list.Where(FindName);
}

private bool FindName(string name)
{
    // Predicate method will compare against whatever class member is set to
    return name == search;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM