C# 我可以用一个方法代替带有额外参数的Lambda表达式吗
我有一个内联lambda表达式,我希望在整个应用程序中使用它。我只是找不到一个关于如何使用比被测试元素更多的参数来实现这一点的参考。下面是我目前拥有的一个快速示例C# 我可以用一个方法代替带有额外参数的Lambda表达式吗,c#,.net,vb.net,C#,.net,Vb.net,我有一个内联lambda表达式,我希望在整个应用程序中使用它。我只是找不到一个关于如何使用比被测试元素更多的参数来实现这一点的参考。下面是我目前拥有的一个快速示例 Private子测试() Dim List作为来自{“Joe”、“Ken”、“Bob”、“John”}的新列表(字符串) Dim搜索为字符串=“*Jo*” Dim结果=列表。其中(函数(名称)名称,如搜索) 端接头 我知道IEnumerable。其中接受元素类型作为参数和返回布尔值的方法 Private子测试() Dim List作
Private子测试()
Dim List作为来自{“Joe”、“Ken”、“Bob”、“John”}的新列表(字符串)
Dim搜索为字符串=“*Jo*”
Dim结果=列表。其中(函数(名称)名称,如搜索)
端接头
我知道IEnumerable。其中
接受元素类型作为参数和返回布尔值的方法
Private子测试()
Dim List作为来自{“Joe”、“Ken”、“Bob”、“John”}的新列表(字符串)
Dim搜索为字符串=“*Jo*”
Dim结果=列表。其中(FindName的地址)
端接头
私有函数FindName(名称为字符串)为布尔值
返回名称,如“*Jo*”
端函数
我还想将搜索变量传递到FindName中。我只是不知道该怎么做。我提出的唯一可行的解决方案是将所有内容传递给函数以执行原始语句
Private子测试()
Dim List作为来自{“Joe”、“Ken”、“Bob”、“John”}的新列表(字符串)
Dim搜索为字符串=“*Jo*”
Dim结果=FindName(列表,搜索)
端接头
私有函数FindName(列表为IEnumerable(属于字符串),搜索为String)为IEnumerable(属于字符串)
返回列表。其中(函数(名称)名称,如搜索)
端函数
不要觉得有义务用VB回答。我会使用扩展方法:-
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
模块1
副标题()
Dim List作为来自{“Joe”、“Ken”、“Bob”、“John”}的新列表(字符串)
Dim搜索为字符串=“*Jo*”
Dim结果=List.FindName(搜索)
端接头
端模块
公共模块扩展
公共函数FindName(列表为IEnumerable(属于字符串),搜索为String)为IEnumerable(属于字符串)
返回列表。其中(函数(名称)名称,如搜索)
端函数
端模块
我认为您不能向Where
方法传递更多参数,但您可以将搜索参数设置为FindName
方法可以访问的类成员。例如(我将用C#写这篇文章,因为这是我比较熟悉的):
string search=“Ken”;
专用无效测试()
{
var list=newlist(){“乔”、“肯”、“鲍勃”、“约翰”};
//在调用查询之前,将搜索成员设置为所需的任何值
search=“乔”;
var result=list.Where(FindName);
}
私有布尔FindName(字符串名称)
{
//谓词方法将与设置为的任何类成员进行比较
返回名称==搜索;
}
lambda表达式的好处在于,它们允许闭包自动捕获作用域的局部变量。例如(请原谅C#):
在上面的代码中,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表达式,将适当的变量传递到执行所有工作的函数中。即使有多个参数,也可以使用:
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" '
再读一遍你的问题后,我不能100%确定这是你真正想要的?我想要的可能在阅读了答案之后不存在。但是扩展将清理单独的函数,因此在我的例子中,扩展将工作得很好。这是一种糟糕的做法。您正在使用全局状态解决局部问题。这很容易导致问题。例如,如果返回结果,则无法控制何时实际执行查询,同时变量可能会更改。如果有多个线程,则会出现相同的问题。直接使用LINQ或像其他人建议的那样使用扩展方法。仔细思考您所说的,我可以理解您的意思,现在我同意您的意见,在多线程环境中也不会起作用。缩短了我的时间。
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);
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" '