2
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

Donno 出了什么问题,但 Module2 工作得很好!

4

2 回答 2

5

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

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

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

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

Dim field As Object = ...
于 2009-04-22T02:30:30.433 回答
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))
于 2009-04-22T03:23:50.163 回答