【发布时间】:2011-05-31 02:46:37
【问题描述】:
我希望尝试更好地理解代表。我查看了 MSDN 和其他各种站点上的示例,但我只是没有“理解”它们。我知道它们实际上类似于 C 中指向函数的指针。但出于某种原因,C 的语法在使用此类结构时更加清晰。
所以我开发了一个场景来尝试使用委托,或者至少在我认为这样的使用是有效的情况下。假设下面的代码属于某种类,并且MyObj 有一个 String 类型的 Name 属性,它返回与对象相同的小写名称(即Obj1.Name = "obj1"):
Private Shared MyList As New List(Of MyObj)(Obj1, Obj2, Obj3, Obj4, Obj5, Obj6)
Private Shared Function FindObj(ByVal obj As MyObj, ByVal name As String) As Boolean
Return String.Equals(obj.Name, name, OrdinalIgnoreCase)
End Function
Friend Shared Sub RedOctober()
Dim obj4Pos As Int32 = -1
For i As Int32 = 0 to (MyList.Count - 1) Step 1
If FindObj(MyList(i), "obj4") Then
obj4Pos = i
Exit For
End If
Next i
If obj4Pos <> -1 Then
Debug.Print("Found obj4!")
Else
Debug.Print("Couldn't find obj4! :(")
End If
End Sub
这是您的基本 O(N)“在列表中搜索匹配的 thingamajig 并在找到时返回索引”。如果我使用FindIndex,我可以将其推断为“更好”的东西,但是:
Private Shared MyList As New List(Of MyObj)(Obj1, Obj2, Obj3, Obj4, Obj5, Obj6)
Friend Shared Sub RedOctober()
Dim obj4Pos As Int32 = MyList.FindIndex(
Function(o) String.Equals(obj.Name, "obj4", OrdinalIgnoreCase))
If obj4Pos <> -1 Then
Debug.Print("Found obj4!")
Else
Debug.Print("Couldn't find obj4! :(")
End If
End Sub
问题是,如果我想搜索的不仅仅是 obj4 怎么办?如果我以这种方式使用 FindIndex,我将需要一个专用的 lambda 表达式/匿名函数来处理我想要查找的 MyObj 的每个对象。这会在生成的二进制文件中添加额外的函数/子程序,它们每个都做大致相同的事情,所以它很臃肿。
如果我保留我的 FindObj 函数并以某种方式在委托中引用它,根据我想在 MyList 中找到的对象,将不同的字符串传递给它,这就是我知道委托可以使用的地方。问题是,FindIndex 想要一个 System.Predicate(Of T) 而我的 FindObj 函数有两个参数:检查 Name 属性的对象和检查它的字符串。
我的问题是:
- 这种情况适合代表吗?
- 是否会比直接使用
For循环更快/更好/更高效/更清洁/选择自己的形容词? - 这是否可行,而是通过纯 lambda 表达式,这样我可以传递我的两个
FindObj参数并找到正确的对象,而无需声明多个具有相似性质的 lambda(因此会增加膨胀)。李> -
FindIndex不是 Linq 的东西,但是有没有一种使用 Linq 的方法可以完成相同的任务,可能会更好(就效率而言——是的,我是一个优化狂,不,我不会为此道歉)?
VB.NET(嗯,一般来说是.NET)的游戏是,通常有多种方法来完成一项任务。困难的部分是找到适合特定情况的方法,不会不必要地臃肿或缓慢,并且对其他审查代码的人(或我在 2-3 个月的中断后)可读。
对于我怀疑的人来说,这应该是一件容易的事。如果我在示例中犯了任何错误,请随时指点并笑:)
【问题讨论】:
-
“委托”这个词只是函数指针的面向对象的名称。 “lambda”这个词只是内联定义的函数的函数式编程词。当您将 lambda 传递给函数时,您只是将地址传递给内联函数。
标签: vb.net