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

标签 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

不知道出了什么问题,但 Module2 工作得很好!

最佳答案

编辑划掉我原来的答案,我误读了问题。

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

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

解决此问题的一个选项是在第一个示例中将字段显式键入为 Object。这将强制它成为后期绑定(bind)调用,并且它将像第二个调用一样进行编译

Dim field As Object = ...

关于vb.net - 使用 vb.net Action(Of T) 和 lambda 声明匿名方法时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/775504/

相关文章:

ios - 目标为 :self not being sent to self? 的 UIButton

c# - .NET 应用程序链接器的状态(又名 "Please Sir, May I have a Linker"2009 版)

java - 最终和有效最终之间的区别

jQuery |单击操作仅在第一次有效

java - 如何查找列表是否包含多个谓词 Java Lambda

linq - 了解 LINQ 中的 =>

php - 如何在 PHP MVC 框架中实现 Controller 操作?

vb.net - WinForm 上的阴影会扭曲界面

vb.net - Entity Framework VB 连接

vb.net - RS.exe 订阅带参数的报告