使用vb.net Action(Of T)和lambda声明匿名方法的问题

Shi*_*mmy 2 vb.net lambda action anonymous-methods

Imports System.Reflection
Public Class Test
    Private Field As String
End Class

Module Module1
    Sub Main()

        Dim field = GetType(Test).GetField("Field", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)

        Dim test = New Test

        Dim GetValue = New Func(Of Test, String)(Function(t As Test) field.GetValue(test))

        'This line indicates a compile error: 'Expression does not produce a value':
        Dim SetValue = New Action(Of Test, String)(Function(t As Test, value As String) field.SetValue(test, value))
    End Sub
 End Module


Module Module2
    Dim field = GetType(Test).GetField("Field", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance) 'Is Shared (Module)
    Sub Main2()
        Dim test = New Test
        Dim GetValue = New Func(Of Test, String)(Function(t As Test) field.GetValue(test))
        Dim SetValue = New Action(Of Test, String)(Function(t As Test, value As String) field.SetValue(test, value))
    End Sub
End Module
Run Code Online (Sandbox Code Playgroud)

Donno有什么不对,但Module2工作得很好!

Jar*_*Par 5

EDIT Scratch我的原始答案,我误解了这个问题.

这不编译的原因是类型推断和后期绑定的问题.在第一个示例中,字段是局部变量,因此可以参与类型推断.编译器将正确推断出类型为FieldInfo.这意味着SetValue调用是静态类型的调用.它是一个void返回方法,因此与需要返回值的Function lambda表达式不兼容.

但是,第二个示例中的字段值是在模块级别声明的.这些变量不受类型推断的影响,因此将选择类型对象.由于类型是object,因此SetValue调用成为后期绑定调用.假定所有后期绑定调用都指向返回类型为Object的函数.在运行时,如果函数返回void,则实际上将返回Nothing.所以在这种情况下,它是一个非void返回表达式,因此编译.

您必须解决此问题的一个选项是在第一个示例中明确键入field作为Object.这将强制它成为一个后期绑定调用,它将像第二个调用一样进行编译

Dim field As Object = ...
Run Code Online (Sandbox Code Playgroud)