我可以使用Method而不是Lambda表达式和额外的参数

时间:2012-01-27 16:19:11

标签: c# .net vb.net

我有一个内联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中回答。

4 个答案:

答案 0 :(得分:6)

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

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

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

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表达式,将适当的变量传递给完成所有工作的函数。

答案 1 :(得分:1)

我会使用扩展方法: -

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

答案 2 :(得分:0)

即使有多个参数,您也可以使用Func(Of T, TResult) Delegate

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" '

答案 3 :(得分:-1)

我认为您不能向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;
}