2012-01-27 25 views
5

Uygulamamda kullanmak istediğim satır içi lambda ifadem var. Bunu test edilen elemandan daha fazla parametreyle nasıl yapacağımıza dair bir referans göremiyorum. İşte şu an sahip olduğum şeyin hızlı bir örneği. Ek parametrelerle Lambda ifadesi yerine bir Yöntem kullanabilir miyim

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 

I IEnumerable.Where bir parametre olarak bir eleman türü ve bir dönen boolean bir yöntem kabul biliyoruz.

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 

Arama değişkenini FindName'e de aktarmak istiyorum. Sadece bunu başarabilen sözdizimini elde edemiyorum. Geldiğim tek çalışma çözümü, orijinal ifadeyi gerçekleştirmek için her şeyi bir işleve aktarmaktır. VB'de yanıt verme zorunluluğu yoktur.

+0

benim [temsilci yaklaşımı] Kısaltılmış (http://stackoverflow.com/a/9036948/284240). –

cevap

6

güzel bir şey onlar kapanışları otomatik yerel değişkenleri yakalamak için sağlamasıdır: Örneğin (yani ben daha aşina olduğum şey olduğu gibi C# bu yazacağım) senin kapsamın. Örneğin, (C# af):

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

Yukarıdaki kodda Search değişken aslında bir kapağın kapsüllenmiş edilmektedir. Sadece bir yöntemi geçmek istiyorsanız, kapanışları gerçek sınıfsal yapısı ile ne simüle etmek gerekir:

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

Ancak bu strateji vakaların küçük bir alt sadece yararlıdır. Ben genellikle uygun değişkenleri tüm işi yapan işleve geçiren bir lambda ifadesi kullanmak en iyisidir.

1

Ben bir uzantısı yöntemini kullanırsınız: -

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

Sorunuzu tekrar okuduktan sonra% 100 emin değilim. – pingoo

+0

Şimdiye kadar cevapları okuduktan sonra neyim var olmayabilir. Ancak uzantı ayrı işlevi temizleyecektir, bu yüzden benim durumumda uzantı iyi çalışacaktır. –

-1

Sana Where yönteme daha argümanlar geçmek sanmıyorum, ama bir sınıf üyesi FindName yöntem olarak arama parametresini ayarlayabilirsiniz erişilebilir. lambda ifadeleri ile

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

Bu kötü bir uygulamadır. Yerel bir sorunu çözmek için global durumu kullanıyorsunuz. Bu kolayca sorunlara yol açabilir. Örneğin sonucu döndürürseniz, sorgunun gerçekte ne zaman yürütüldüğüne dair kontrolünüz yoktur, değişken değişebilir. Birden fazla iş parçacığınız varsa aynı sorun. Doğrudan LINQ veya önerilenler gibi bir uzantı yöntemini kullanın. – aKzenT

+0

Söylediklerinizle düşünmek, ne demek istediğini görebiliyorum ve şimdi sizinle aynı fikirdeyim, asla çok iş parçacıklı bir bağlamda çalışmaz. –

0

Hatta birden parametrelerle bir Func(Of T, TResult) Delegate kullanabilirsiniz:

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" ' 
İlgili konular