Pregunta

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 lo que está mal, pero Module2 funciona muy bien!

¿Fue útil?

Solución

Editar Ráscame respuesta original, leí mal el problema.

La razón de que esto no se compila es un problema de inferencia de tipos y el enlace en tiempo. En el primer campo ejemplo es una variable local y por lo tanto puede participar en la inferencia de tipos. El compilador deducir correctamente el tipo de ser FieldInfo. Esto significa que la llamada es una llamada FijarValor tipos estáticos. Es un método de volver vacío y es por lo tanto, incompatible con una expresión de función lambda que requiere un valor de retorno.

El valor del campo en el segundo ejemplo, aunque se declara en un nivel de módulo. Estas variables no están sujetos a la inferencia de tipos y por lo tanto será elegido el objeto de texto. Dado que el tipo es objeto, la llamada FijarValor se convierte en una llamada enlazada tarde. Todas las llamadas con destino finales se supone que apuntar a una función que tiene un tipo de retorno del objeto. En tiempo de ejecución, si la función devuelve void, en realidad será devuelto nada. Así pues, en este contexto, es una expresión devolviendo no nula y, por tanto, compila.

Una de las opciones que usted tiene que trabajar alrededor de esto es que escribir de forma explícita como campo de objetos en el primer ejemplo. Esto obligará a que sea una llamada enlazada tarde y se compilará al igual que el segundo

Dim field As Object = ...

Otros consejos

Bueno, aquí está la respuesta final basada en el post de 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

Tenga en cuenta el reparto de oponerse a

Dim SetValue = New Action(Of Test, String)(Function(t As Test, value As String) DirectCast(field, Object).SetValue(test, value))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top