VB.Net List.Find。将值传递给谓词

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2655793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 14:50:16  来源:igfitidea点击:

VB.Net List.Find. Pass values to predicate

vb.net

提问by Beta033

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

使用带有自定义谓词的 List.Find 时遇到一些麻烦

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)

这样做意味着我必须在类中有一个共享的“currentKey”对象,而且我知道必须有一种方法来传递我对 CurrentKey 感兴趣的值(即,keyname 和 oldkey)

ideally i'd like to call it by something like keys.Find(AddressOf FindByOldKeyAndName(Name,OldVal))

理想情况下,我想这样称呼它 keys.Find(AddressOf FindByOldKeyAndName(Name,OldVal))

however when i do this i get compiler errors.

但是,当我这样做时,我会收到编译器错误。

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

我如何调用此方法并传入值?

回答by Hans Passant

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

您可以使用 VS2008 及更高版本中的 lambda 表达式干净地解决此问题。一个愚蠢的例子:

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 threadfor a cleaner solution.

对于早期版本,您必须将“currentKey”设为类的私有字段。在此线程中检查我的代码以获得更清洁的解决方案。

回答by Scott

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

回答by Hans Olsson

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.

我不需要在较新版本的 VB.Net 中尝试这个,这可能有更好的方法,但在旧版本中,我所知道的唯一方法是在你的班级中有一个共享成员在称呼。
网上有各种各样的示例,人们创建小型实用程序类来包装它以使其更好一些。

回答by bendecko

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

有关更多示例,包括日期搜索,请参阅 Mike McIntyre 的博客文章