Problem der Deklaration einer anonymen Methode mit vb.net Action(Of T) und 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
Donno was falsch ist, sondern "Modul2" funktioniert einfach toll!
Du musst angemeldet sein, um einen Kommentar abzugeben.
BEARBEITEN Kratzen meine ursprüngliche Antwort habe ich falsch verstanden, das problem.
Den Grund, warum das nicht kompilieren, ist eine Frage, die Typ-Inferenz und die späte Bindung. In der ersten Beispiel-Feld wird eine lokale variable und kann daher die Teilnahme in der Typ-Inferenz. Der compiler korrekt ableiten der Typ FieldInfo. Dies bedeutet, dass das SetValue-call ist eine statisch typisierte nennen. Es ist ein void-Rückgabe-Methode und ist daher unvereinbar mit einer Funktion lambda-Ausdruck erfordert einen Wert zurück.
Den Wert des Feldes in das zweite Beispiel ist zwar deklariert ein Modul-Ebene. Diese Variablen sind nicht Gegenstand der Typ-Inferenz und damit auch die Art-Objekt gewählt werden. Da ist der Typ object, der SetValue-Aufruf wird ein spät gebundenes nennen. Alle spät gebundene Aufrufe angenommen werden zu einem Punkt die Funktion hat einen Rückgabetyp des Objekts. Zur Laufzeit, wenn die Funktion, die void zurückgibt, wird Nichts tatsächlich zurückgegeben werden. So ist in diesem Zusammenhang eine non-void Rückgabe Ausdrucks und damit kompiliert.
Eine option, die Sie haben, um dies zu umgehen, ist der explizite Typ-Feld als Objekt in dem ersten Beispiel. Dies zwingt Sie, um eine späte Bindung nennen und es kompilieren wird ebenso wie die zweite
Also hier ist die endgültige Antwort auf JaredPar post:
Beachten Sie die cast-Objekt an