开发者

VB.Net List.Find. Pass values to predicate

开发者 https://www.devze.com 2022-12-26 23:22 出处:网络
Having a bit of trouble using the List.Find with a custom predicate i have a function that does this private function test ()

Having a bit of trouble using the List.Find with a custom predicate

i have a function that does this

private function test ()
    Dim test As Integer = keys.Find(AddressOf FindByOldKeyAndName).NewKey

here's the function for the predicate

Private Shared Function FindByOldKeyAndName(ByVal k As KeyObj) As Boolean
        If k.OldKey = currentKey.OldKey And k.KeyName = currentKey.KeyName Then
            Return True
        Else
            Return False
        End If


    End Function

by doing it this way means i have to have a shared "currentKey" object in the class, and i know there has to be a way to pass in the values i'm interested in of CurrentKey (namely, keyname, and oldkey)

ideally i'd like to call it by something like keys.Fin开发者_开发技巧d(AddressOf FindByOldKeyAndName(Name,OldVal))

however when i do this i get compiler errors.

How do i call this method and pass in the values?


You can cleanly solve this with a lambda expression, available in VS2008 and up. A silly example:

Sub Main()
    Dim lst As New List(Of Integer)
    lst.Add(1)
    lst.Add(2)
    Dim toFind = 2
    Dim found = lst.Find(Function(value As Integer) value = toFind)
    Console.WriteLine(found)
    Console.ReadLine()
End Sub

For earlier versions you'll have to make "currentKey" a private field of your class. Check my code in this thread for a cleaner solution.


I have an object that manages a list of Unique Property Types. Example:

obj.AddProperty(new PropertyClass(PropertyTypeEnum.Location,value))
obj.AddProperty(new PropertyClass(PropertyTypeEnum.CallingCard,value))
obj.AddProperty(new PropertyClass(PropertyTypeEnum.CallingCard,value)) 
//throws exception because property of type CallingCard already exists

Here is some code to check if properties already exist

Public Sub AddProperty(ByVal prop As PropertyClass)
    If Properties.Count < 50 Then
        'Lets verify this property does not exist
        Dim existingProperty As PropertyClass = _
            Properties.Find(Function(value As PropertyClass)
                Return value.PropertyType = prop.PropertyType
            End Function)

        'if it does not exist, add it otherwise throw exception
        If existingProperty Is Nothing Then
            Properties.Add(prop)
        Else
            Throw New DuplicatePropertyException("Duplicate Property: " + _
                         prop.PropertyType.ToString())
        End If

    End If
End Sub


I haven't needed to try this in newer versions of VB.Net which might have a nicer way, but in older versions the only way that I know of would be to have a shared member in your class to set with the value before the call.
There's various samples on the net of people creating small utility classes to wrap this up to make it a little nicer.


I've found a blog with a better "real world" context example, with good variable names.

The key bit of code to Find the object in the list is this:

      ' Instantiate a List(Of Invoice).
        Dim invoiceList As New List(Of Invoice)

        ' Add some invoices to List(Of Invoice).
        invoiceList.Add(New Invoice(1, DateTime.Now, 22))
        invoiceList.Add(New Invoice(2, DateTime.Now.AddDays(10), 24))
        invoiceList.Add(New Invoice(3, DateTime.Now.AddDays(30), 22))
        invoiceList.Add(New Invoice(4, DateTime.Now.AddDays(60), 36))

        ' Use a Predicate(Of T) to find an invoice by its invoice number.
        Dim invoiceNumber As Integer = 1
        Dim foundInvoice = invoiceList.Find(Function(invoice) invoice.InvoiceNumber = invoiceNumber)

For more examples, including a date search, refer to Mike McIntyre's Blog Post

0

精彩评论

暂无评论...
验证码 换一张
取 消