是否有人能够告诉我VB中Func
和Function
之间的区别。
例如,请参阅以下内容:
Dim F As Func(Of String) = Function() As String
Return "B"
End Function
Dim F2 = Function() As String
Return "B"
End Function
F
显示为Func(Of String)
F2
为Function() As String
。看起来他们做同样的事情,但鉴于编译器认为它们具有不同的类型,肯定必须有一个sublity。
祝你好运
查尔斯
答案 0 :(得分:4)
F作为Func(Of String)F2显示为Function()为字符串。
不,它没有。在这两种情况下,变量类型都是一个等同于Func(Of String)
的委托。仔细查看代码 - 两个声明都有两个部分;声明本身:
Dim F As Func(Of String)
' and
Dim F2
......和初始化:
Function() As String
Return "B"
End Function
' and
Function() As String
Return "B"
End Function
如您所见,初始化是相同的。仅仅声明是不同的,因为我们在第二种情况下省略了显式变量类型。感谢Option Infer
,编译器可以为我们推断它。
事实上,VB语言规范就是这样说的(§8.4.2):
当分类为lambda方法的表达式在没有目标类型的上下文中重新分类为值时(例如,
Dim x = Function(a As Integer, b As Integer) a + b
),结果表达式的类型是匿名委托类型相当于lambda方法的签名。 [强调我的]
最后,Func
和Function
之间的区别是什么?
Function
是一个关键字,它引入了一个函数 - 代码中的匿名函数(lambda)或具有名称的“普通”函数,如下代码所示: / p>
Function F() As String
Return "B"
End Function
另一方面, Func(Of T…)
是委托的泛型类型。 lambda或委托可以绑定到使用拟合Func
类型声明的变量。这发生在您的代码中。
答案 1 :(得分:4)
Func(Of TResult)()
是一个名为Func
的特定代表。它是在System
命名空间内声明的类型,如下所示:
Public Delegate Function Func(Of TResult)() As TResult
可能有不同的名称。例如:
Public Delegate Function MyParameterLessFunction(Of TResult)() As TResult
所以Func
实际上只是给代表的名字。由于未明确指定F2
的类型,因此VB不知道此委托的名称。是Func
还是MyParameterLessFunction
还是其他什么?相反,VB只显示其签名Function() As String
,因为F2
也适合声明为
Public Delegate Function AnonymousParameterLessStringFunction() As String
在评论中,您使用.ToString()
和F
上的F2
。这将返回运行时类型,即分配给这些变量的值的类型。这些类型可以与这些变量的静态类型不同,即,给变量名称赋予的类型。让我们做一点测试
Imports System.Reflection
Module FuncVsFunction
Dim F As Func(Of String) = Function() As String
Return "B"
End Function
Dim F2 = Function() As String
Return "B"
End Function
Sub Test()
Console.WriteLine($"Run-time type of F: {F.ToString()}")
Console.WriteLine($"Run-time type of F2: {F2.ToString()}")
Dim moduleType = GetType(FuncVsFunction)
Dim fields As IEnumerable(Of FieldInfo) = moduleType _
.GetMembers(BindingFlags.NonPublic Or BindingFlags.Static) _
.OfType(Of FieldInfo)
For Each member In fields
Console.WriteLine($"Static type of {member.Name}: {member.FieldType.Name}")
Next
Console.ReadKey()
End Sub
End Module
显示
Run-time type of F: System.Func`1[System.String]
Run-time type of F2: VB$AnonymousDelegate_0`1[System.String]
Static type of F: System.Func`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Static type of F2: System.Object
请注意,F2
只需输入Object
即可。这是一个惊喜。我希望它是一个委托类型。
您还会在调试器中看到这种差异。如果您将断点设置为Test
方法,然后将鼠标悬停在Dim
和F
的{{1}}个关键字上,则会显示一个弹出窗口
F2
如果将鼠标悬停在变量名称
上'Dim of F (static type)
Delegate Function System.Func(Of Out TResult)() As String
'Dim of F2 (static type)
Class System.Object
对于'F (run-time type)
Method = {System.String _Lambda$__0-0()}
'F2 (run-time type)
<generated method>
,您不仅可以获取类型信息,还可以获取生成的方法本身的名称。由于F
是一个对象,因此Visual Studio显然不会像F2
一样深入。
答案 2 :(得分:0)
Func
是委托类型 - System.Func。
Function
是用于创建lambda表达式的关键字。
上述lambda表达式的类型为System.Linq.Expression(Of System.Func(Of String)),并且可以隐式转换为委托类型Func(Of String)。
不同之处在于表达式存储为表达式树 - 描述代码的结构。在隐式转换期间,它实际上被编译为委托。