2012-01-27 26 views
5

Tôi có biểu thức lambda nội tuyến mà tôi muốn sử dụng trong suốt ứng dụng của mình. Tôi chỉ có vẻ không thể tìm thấy một tài liệu tham khảo về cách làm điều này với nhiều thông số hơn so với các yếu tố đang được thử nghiệm. Đây là một ví dụ nhanh về những gì tôi hiện có.Tôi có thể sử dụng Phương thức thay vì biểu thức Lambda với tham số bổ sung

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 

Tôi biết phương thức là loại tham số và boolean trả về.

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 

Tôi cũng muốn chuyển biến Tìm kiếm vào Tìm tên. Tôi chỉ không thể có được cú pháp figured thực hiện điều này. Giải pháp làm việc duy nhất mà tôi đưa ra là chuyển mọi thứ đến một hàm để thực hiện câu lệnh gốc.

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 

Không cảm thấy bị bắt buộc phải trả lời trong VB.

+0

rút gọn [cách tiếp cận đại biểu] của tôi (http://stackoverflow.com/a/9036948/284240). –

Trả lời

6

Những điều tốt đẹp với các biểu thức lambda là họ cho phép đóng cửa tự động chụp các biến mà là cục bộ đối phạm vi của bạn. Ví dụ (pardon C#):

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

Trong đoạn mã trên, biến Search thật sự đang được gói gọn trong một đóng cửa. Nếu bạn chỉ muốn vượt qua một phương pháp, bạn sẽ phải mô phỏng những gì đóng cửa với cấu trúc lớp thực tế:

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); 

Tuy nhiên, chiến lược này chỉ hữu ích trong một nhóm nhỏ các trường hợp. Tôi tìm thấy nó thường là tốt nhất để chỉ cần sử dụng một biểu thức lambda mà vượt qua các biến thích hợp vào chức năng mà tất cả các công việc.

1

Tôi sẽ sử dụng một phương pháp mở rộng: -

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 
+0

Có đọc câu hỏi của bạn một lần nữa tôi không chắc chắn 100% đây là những gì thực sự của bạn sau? – pingoo

+0

Những gì tôi đã có sau khi có thể không tồn tại sau khi đọc câu trả lời cho đến nay. Nhưng phần mở rộng sẽ dọn sạch chức năng riêng biệt, vì vậy trong trường hợp của tôi, phần mở rộng sẽ hoạt động tốt. –

-1

Tôi không nghĩ rằng bạn có thể vượt qua trong lập luận hơn với phương pháp Where, nhưng bạn có thể thiết lập thông số tìm kiếm của bạn như là một thành viên lớp mà phương pháp FindName có thể truy cập. Ví dụ (Tôi sẽ viết những dòng này trong C# như đó là những gì tôi quen thuộc hơn với):

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; 
} 
+1

Đây là thực hành không tốt. Bạn đang sử dụng trạng thái toàn cầu để giải quyết một vấn đề cục bộ. Điều này có thể dễ dàng dẫn đến các vấn đề. Nếu bạn trả lại kết quả ví dụ bạn không có quyền kiểm soát khi truy vấn thực sự được thực thi trong khi đó biến có thể thay đổi. Cùng một vấn đề nếu bạn có nhiều chủ đề. Sử dụng LINQ trực tiếp hoặc một phương pháp mở rộng như những người khác được đề xuất. – aKzenT

+0

Suy nghĩ qua những gì bạn nói tôi có thể thấy ý bạn và bây giờ đồng ý với bạn, sẽ không bao giờ làm việc trong ngữ cảnh đa luồng. –

0

Bạn có thể sử dụng một Func(Of T, TResult) Delegate ngay cả với nhiều tham số:

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" ' 
Các vấn đề liên quan