2009-04-22 24 views
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はうまく動作します!vb.netでの匿名メソッドの宣言の問題アクション(Of T)とラムダ

答えて

5

EDITスクラッチ私の元の答え、私は問題を誤解しました。

これはコンパイルされない理由は、型推論と遅延バインディングの問題です。最初の例では、ローカル変数があり、型推論に参加することができます。コンパイラは型をFieldInfoに正しく推定します。これは、SetValue呼び出しが静的に型指定された呼び出しであることを意味します。 voidを返すメソッドであるため、戻り値を必要とする関数のラムダ式と互換性がありません。

しかし、2番目の例のフィールド値は、モジュールレベルで宣言されています。これらの変数は型推論の対象ではないため、型オブジェクトが選択されます。タイプはオブジェクトなので、SetValueコールは遅延バインドコールになります。すべての遅延バインドされた呼び出しは、オブジェクトの戻り値の型を持つ関数を指しているとみなされます。実行時に関数がvoidを返すと、実際には何も返されません。したがって、この文脈では、非空白の戻り式であり、したがってコンパイルされます。

この問題を回避するには、最初の例でフィールドをObjectとして明示的に入力する必要があります。これは、遅延バインディング呼び出しすることを強制し、それはさてここだけ秒1

Dim field As Object = ... 
+1

なぜ2番目のものが正常に機能しますか? –

+0

donno、それは を試してみてください – Shimmy

+1

@Nathan、私は問題を誤読し、私の答えを更新しました。 – JaredPar

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)) 
関連する問題