VB.Netでラムダイベントハンドラを宣言する方法は?
-
03-07-2019 - |
質問
次のVB.Netコードは、進行中のC#コードと同等であると考えています。ただし、VB.Netテストは失敗します-Lambdaを処理するイベントは呼び出されません。
何が起こっているのですか?
VB.Netバージョン-失敗:
<TestFixture()> _
Public Class TestClass
<Test()> _
Public Sub EventTest()
Dim eventClass As New EventClass
Dim eventRaised As Boolean = False
AddHandler eventClass.AnEvent, Function() (eventRaised = True)
eventClass.RaiseIt()
Assert.IsTrue(eventRaised)
End Sub
End Class
Public Class EventClass
Public Event AnEvent()
Public Sub RaiseIt()
RaiseEvent AnEvent()
End Sub
End Class
C#バージョン-パス:
[TestFixture]
public class TestClass
{
[Test]
public void EventTest()
{
var eventClass = new EventClass();
var eventRaised = false;
eventClass.AnEvent += () => { eventRaised = true; };
eventClass.RaiseIt();
Assert.IsTrue(eventRaised);
}
}
public class EventClass
{
public delegate void EventHandler();
public event EventHandler AnEvent;
public void RaiseIt()
{
AnEvent();
}
}
解決 2
注:これは、Visual Studio 2010およびVB.net 10より前の古いバージョンのVB.netに関連しています
違いは、VB.Netではラムダ式が値を返す必要があることです。つまり、それらはsubsではなく関数でなければなりません。ラムダ式 eventRaised = true
は、割り当てではなくブール式として解釈されています。つまり、trueに設定するのではなくfalseに評価しています。
MSDN の詳細。
この例で使用されているイベントをテストするためのc#パターンは、別の関数を導入せずにVB.Netで実行できるとは思わない
<TestFixture()> _
Public Class Test
<Test()> _
Public Sub EventTest()
Dim eventClass As New EventClass
Dim eventRaised As Boolean = False
AddHandler eventClass.AnEvent, Function() (SetValueToTrue(eventRaised))
eventClass.RaiseIt()
Assert.IsTrue(eventRaised)
End Sub
Private Function SetValueToTrue(ByRef value As Boolean) As Boolean
value = True
Return True
End Function
End Class
Public Class EventClass
Public Event AnEvent()
Public Sub RaiseIt()
RaiseEvent AnEvent()
End Sub
End Class
他のヒント
今この質問を見つけている人のために:Visual Basic 2010(VB 10.0)以降、匿名の Sub
は機能するので、次のように書くことができます:
Sub() eventRaised = True
簡単に言えば、今のところVBでそれを行うことはできません(次のリリースで考慮される機能のリストに載っています)。宣言されたメソッドとAddressOf演算子を使用する必要があります。
VBチームには、言語に匿名のデリゲートを含める時間がありませんでした(技術的にはラムダ式ではなく、使用しようとしているものです)。
Linqが実際に機能するためには、ラムダ式を実装する必要がありました。匿名のデリゲートは何にも必要ありません(ただし、非常に便利です)。彼らはLinq To XMLやXMLのリタラルのようなものをまとめ、構文にクエリ演算子を統合することにもっと時間を費やしたと思います...