Question

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 ce qui est mal, mais Module2 fonctionne tout simplement génial!

Était-ce utile?

La solution

EDIT Grattez ma première réponse, j'ai mal lu le problème.

La raison pour laquelle cela ne compile pas est une question de l'inférence de type et la liaison tardive. Dans le premier champ exemple est une variable locale et peut donc participer à l'inférence de type. Le compilateur correctement déduit du type à FieldInfo. Cela signifie que l'appel SetValue est un appel statiquement typé. Il est une méthode de retour de vide et est donc incompatible avec une expression lambda fonction qui nécessite une valeur de retour.

La valeur du champ dans le deuxième exemple est déclarée mais à un niveau de module. Ces variables ne sont pas soumis à l'inférence de type et par conséquent l'objet de type sera choisi. Étant donné que le type est objet, l'appel SetValue devient un appel en retard lié. Tous les appels en retard liés sont supposés pointer vers une fonction qui a un type de retour de l'objet. Lors de l'exécution si la fonction retourne vide, rien ne sera effectivement retourné. Donc, dans ce contexte, il est une expression renvoie une valeur non vide et compile donc.

L'une des options que vous avez à contourner est de taper explicitement champ comme objet dans le premier exemple. Cela forcera à être un appel en retard lié et il compilera tout comme le second

Dim field As Object = ...

Autres conseils

est bien ici la réponse finale basée sur le 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

Remarquez la distribution à l'objet à

Dim SetValue = New Action(Of Test, String)(Function(t As Test, value As String) DirectCast(field, Object).SetValue(test, value))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top