vb.net VB 中的函数 vs 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17469541/
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
Func vs Function in VB
提问by Charles
Would anyone be able to tell me what is the difference between a Funcand a Functionin VB.
谁能告诉我VB 中的aFunc和 a之间有什么区别Function。
For instance see the following:
例如,请参见以下内容:
Dim F As Func(Of String) = Function() As String
Return "B"
End Function
Dim F2 = Function() As String
Return "B"
End Function
Fappears as aFunc(Of String)F2as aFunction() As String.
F显示为Func(Of String)F2作为Function() As String.
It looks like they do the same thing but given that the compiler sees them as having different types surely there must be a subtlity.
看起来它们做同样的事情,但考虑到编译器认为它们具有不同的类型,肯定会有微妙之处。
Best regards
此致
Charles
查尔斯
采纳答案by Olivier Jacot-Descombes
Func(Of TResult)()is a specific delegate with the name Func. It is a type declared inside the Systemnamespace as follows:
Func(Of TResult)()是一个名为 的特定委托Func。它是在System命名空间内声明的类型,如下所示:
Public Delegate Function Func(Of TResult)() As TResult
It could have been named differently. For instance:
它可以以不同的方式命名。例如:
Public Delegate Function MyParameterLessFunction(Of TResult)() As TResult
So Funcis really just the name given to a delegate. Since the type of F2is not specified explicitly, VB does not know a name for this delegate. Is it Funcor MyParameterLessFunctionor something else? Instead, VB just displays its signature Function() As String, since F2does also fit a non-generic delegate declared as
所以Func实际上只是赋予代表的名称。由于F2未明确指定的类型,VB 不知道此委托的名称。它是Func或者MyParameterLessFunction还是其他什么东西?相反,VB 只显示它的签名Function() As String,因为F2它也适合声明为的非泛型委托
Public Delegate Function AnonymousParameterLessStringFunction() As String
In your comment you use .ToString()on Fand F2. This returns the run-time types, i.e., the types of the values assigned to these variables. These types can be different from the static types of these variables, i.e., the type given to the variable name. Let's make a little test
在您的评论中,您使用.ToString()onF和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
It displays
它显示
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
Note that F2is simply typed as Object. This is a surprise. I expected it to be a of a delegate type.
请注意,F2它只是简单地输入为Object. 这是一个惊喜。我希望它是一个委托类型。
You also see this difference in the debugger. If you set a break point into the Testmethod and then hover over the Dimkeywords of Fand F2, a popup displays
您还会在调试器中看到这种差异。如果您在Test方法中设置断点,然后将鼠标悬停在and的Dim关键字上F,则会F2显示一个弹出窗口
'Dim of F (static type)
Delegate Function System.Func(Of Out TResult)() As String
'Dim of F2 (static type)
Class System.Object
If you hover over the variable names
如果将鼠标悬停在变量名称上
'F (run-time type)
Method = {System.String _Lambda$__0-0()}
'F2 (run-time type)
<generated method>
For Fyou not only get type information but also the name of the generated method itself. Since F2is an Object, Visual Studio obviously does not dig as deep as for F.
因为F您不仅可以获得类型信息,还可以获得生成的方法本身的名称。由于F2是一个对象,Visual Studio 显然没有像F.
回答by Konrad Rudolph
F appears as a Func(Of String) F2 as a Function() as string.
F 作为一个 Func(Of String) F2 作为一个 Function() 作为字符串出现。
No, it doesn't. In both cases the variable type is a delegate that's equivalent to Func(Of String). Look at the code carefully again – both declarations have two parts; the declaration itself:
不,它没有。在这两种情况下,变量类型都是等效于Func(Of String). 再仔细看看代码——两个声明都有两部分;声明本身:
Dim F As Func(Of String)
' and
Dim F2
… and the initialisation:
......和初始化:
Function() As String
Return "B"
End Function
' and
Function() As String
Return "B"
End Function
As you can see, the initialisation is identical. Merely the declaration is different because we omitted the explicit variable type in the second case. Thanks to Option Infer, the compiler can infer it for us.
如您所见,初始化是相同的。只是声明不同,因为我们在第二种情况下省略了显式变量类型。感谢Option Infer,编译器可以为我们推断出来。
In fact, the VB language specification has this to say (§8.4.2):
其实VB语言规范是这么说的(§8.4.2):
When an expression classified as a lambda method is reclassified as a value in a context where there is no target type (for example,
Dim x = Function(a As Integer, b As Integer) a + b), the type of the resulting expression is an anonymous delegate type equivalent to the signature of the lambda method. [emphasis mine]
当归类为 lambda 方法的表达式在没有目标类型(例如,
Dim x = Function(a As Integer, b As Integer) a + b)的上下文中被重新归类为值时,生成的表达式的类型是匿名委托类型,等效于 lambda 方法的签名。[强调我的]
Finally, what, then, is the difference between Funcand Function?
最后,那么,Func和之间的区别是Function什么?
Functionis a keywordthat introduces a function – either anonymous function (lambda) as in your code, or a “normal” function having a name, as in this code:
Function是一个引入函数的关键字——要么是代码中的匿名函数 (lambda),要么是具有名称的“普通”函数,如以下代码:
Function F() As String
Return "B"
End Function
Func(Of T…)on the other hand is a generic typefor a delegate. A lambda or a delegate can be bound to a variable declared with a fitting Functype. This is happening in your code.
Func(Of T…)另一方面是委托的泛型类型。可以将 lambda 或委托绑定到使用合适Func类型声明的变量。这发生在您的代码中。
回答by Jan Dobkowski
Funcis a delegate type - System.Func.
Func是委托类型 - System.Func。
Functionis a keyword used to create lambda expressions.
Function是用于创建 lambda 表达式的关键字。
The above lambda expressions are of type System.Linq.Expression(Of System.Func(Of String))and are indeed implicitly convertible to the delegate type Func(Of String).
上面的 lambda 表达式属于System.Linq.Expression(Of System.Func(Of String)) 类型,并且确实可以隐式转换为委托类型Func(Of String)。
The difference is that the expression is stored as an expression tree - describing the structure of the code. During the implicit conversion it is actually compiled into a delegate.
不同之处在于表达式存储为表达式树——描述代码的结构。在隐式转换期间,它实际上被编译成一个委托。

