【问题标题】:Problem declaring an anonymous method with vb.net Action(Of T) and lambda使用 vb.net Action(Of T) 和 lambda 声明匿名方法时出现问题
【发布时间】:2010-10-21 00:04:38
【问题描述】:
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 工作得很好!

【问题讨论】:

    标签: vb.net lambda action anonymous-methods


    【解决方案1】:

    这是基于 JaredPar 帖子的最终答案:

    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) DirectCast(field, Object).SetValue(test, value))
        End Sub
    End Module
    

    请注意在

    处对对象的强制转换
    Dim SetValue = New Action(Of Test, String)(Function(t As Test, value As String) DirectCast(field, Object).SetValue(test, value))
    

    【讨论】:

      【解决方案2】:

      编辑刮掉我原来的答案,我看错了问题。

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

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

      您必须解决此问题的一个选项是在第一个示例中将字段显式键入为对象。这将迫使它成为一个后期绑定调用,它会像第二个调用一样编译

      Dim field As Object = ...
      

      【讨论】:

      • 我更喜欢投射它,因为在更多情况下我需要它直接使用它。看帖子。
      • 同时享受智能感知支持。
      猜你喜欢
      • 1970-01-01
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多