使用 vb.net Action(Of T) 和 lambda 声明匿名方法时出现问题
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 工作得很好!
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 what's wrong but Module2 works just great!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编辑划掉我原来的答案,我误读了问题。
无法编译的原因是类型推断和后期绑定的问题。 在第一个示例中,字段是局部变量,因此可以参与类型推断。 编译器将正确推断类型为 FieldInfo。 这意味着 SetValue 调用是静态类型调用。 它是一个 void 返回方法,因此与需要返回值的 Function lambda 表达式不兼容。
不过,第二个示例中的字段值是在模块级别声明的。 这些变量不受类型推断的影响,因此将选择类型对象。 由于类型是对象,因此 SetValue 调用成为后期绑定调用。 假定所有后期绑定调用都指向返回类型为 Object 的函数。 在运行时,如果函数返回 void,则实际上不会返回任何内容。 因此,在这种情况下,它是一个非 void 返回表达式,因此可以编译。
解决此问题的一个选项是在第一个示例中将字段显式键入为 Object。 这将迫使它成为后期绑定调用,并且它将像第二个调用一样进行编译
EDIT Scratch my original answer, I misread the problem.
The reason this does not compile is an issue of type inference and late binding. In the first example field is a local variable and hence can participate in type inference. The compiler will correctly deduce the type to be FieldInfo. This means the SetValue call is a statically typed call. It is a void returning method and is hence incompatible with a Function lambda expression which requires a return value.
The field value in the second example though is declared at a module level. These variables are not subject to type inference and hence the type object will be chosen. Since the type is object, the SetValue call becomes a late bound call. All late bound calls are assumed to point to a function that has a return type of Object. At runtime if the function returns void, Nothing will actually be returned. So in this context it is a non-void returning expression and hence compiles.
One option you have to work around this is to explicitly type field as Object in the first example. This will force it to be a late bound call and it will compile just like the second one
这是基于 JaredPar 的帖子的最终答案:
Notice thecast to object at
Well here is the final answer based on JaredPar's post:
Notice the cast to object at