Func vs function in VB

Can anyone tell me what is the difference between Func and Function in VB.

For example, 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 
  • F appears as Func(Of String)
  • F2 as Function() As String .

It looks like they are doing the same thing, but given that the compiler sees them as different types, there certainly should be subtlety.

Best wishes

Charles

+8
source share
3 answers

Func(Of TResult)() is a special delegate named Func . This is a type declared inside the System namespace as follows:

 Public Delegate Function Func(Of TResult)() As TResult 

It could be called differently. For instance:

 Public Delegate Function MyParameterLessFunction(Of TResult)() As TResult 

So Func is just the name given to the delegate. Because type F2 not explicitly specified, VB does not know the name for this delegate. Is it Func or MyParameterLessFunction or something else? Instead, VB simply displays its signature Function() As String , since F2 also suitable for a non-universal delegate declared as

 Public Delegate Function AnonymousParameterLessStringFunction() As String 

In your comment, you use .ToString() on F and F2 . This returns runtime types, that is, the types of values ​​assigned to these variables. These types may differ from the static types of these variables, i.e. The type to be assigned to the variable name. Let's do a little test

 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 

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 F2 simply entered as an Object . It's a surprise. I expected this to be a delegate type.


You also see this difference in the debugger. If you set the Test point to the Test method and then hover over the keywords Dim F and F2 , a pop-up window will appear.

 '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 variable names

 'F (run-time type) Method = {System.String _Lambda$__0-0()} 'F2 (run-time type) <generated method> 

For F you get not only type information, but also the name of the generated method itself. Since F2 is an object, Visual Studio obviously does not dig as deep as for F

+4
source

F appears as Func (Of String) F2 as a function () as a string.

No, it is not. In both cases, the variable type is the delegate equivalent to Func(Of String) . Take a close look at the code - both declarations are in two parts; declaration itself:

 Dim F As Func(Of String) ' and Dim F2 

... and initialization:

 Function() As String Return "B" End Function ' and Function() As String Return "B" End Function 

As you can see, the initialization is identical. It’s just that the declaration is different from the fact that we omitted the type of the explicit variable in the second case. Thanks to Option Infer compiler can do this for us.

In fact, the VB language specification has this to say (§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 type of delegation, equivalent to the signature lambda method. [emphasis mine]

Finally, what is the difference between Func and Function ?

Function is a keyword that introduces a function - either an anonymous function (lambda), as in your code, or a "normal" function that has a name, as in this code:

 Function F() As String Return "B" End Function 

Func(Of T…) , on the other hand, is a generic type for a delegate. A lambda or delegate can be bound to a variable declared with a suitable type of Func . This happens in your code.

+4
source

Func - the type of delegate is System.Func .

Function is a keyword used to create lambda expressions.

The above lambda expressions are of type System.Linq.Expression (Of System.Func (Of String)) and are really implicitly converted to the delegate type Func (Of String) .

The difference is that the expression is stored as an expression tree that describes the structure of the code. During an implicit conversion, it is actually compiled into a delegate.

0
source

Source: https://habr.com/ru/post/948706/


All Articles