Comment déclarer des gestionnaires d'événements lambda dans VB.Net?
-
03-07-2019 - |
Question
Je crois que le code VB.Net suivant est l’équivalent du code C # précédent; cependant, le test VB.Net échoue - la gestion d'événements Lambda n'est jamais appelée.
Que se passe-t-il?
Version VB.Net - échoue:
<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
Version C # - passe:
[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();
}
}
La solution 2
Remarque: cela concerne les anciennes versions de VB.net antérieures à Visual Studio 2010 et VB.net 10
.
La différence est qu’en VB.Net une expression lambda doit renvoyer une valeur, c’est-à-dire qu’il doit s'agir de fonctions et non de sous-unités. L’expression lambda eventRaised = true
est interprétée comme une expression booléenne plutôt qu’une affectation, c’est-à-dire qu’elle est évaluée à false plutôt que définie sur true.
Plus de détails sur MSDN .
Je ne pense pas que le modèle c # pour tester les événements utilisés dans l'exemple puisse être créé dans VB.Net sans introduire une autre fonction, par exemple.
<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
Autres conseils
Pour ceux qui trouvent cette question maintenant: depuis Visual Basic 2010 (VB 10.0), les Sub anonymes
anonymes fonctionnent, vous pouvez donc écrire quelque chose comme:
Sub() eventRaised = True
En résumé, vous ne pouvez pas le faire en VB pour l’instant (c’est la liste des fonctionnalités considérées pour la prochaine version). Vous devez utiliser une méthode déclarée et l'opérateur AddressOf.
L'équipe VB n'a pas eu le temps d'inclure des délégués anonymes dans la langue (c'est ce que vous essayez d'utiliser, techniquement, pas une expression lambda).
Les expressions lambda qu’ils devaient implémenter pour que Linq puisse fonctionner. Les délégués anonymes ne sont requis par rien (mais seraient très utiles). Je suppose qu'ils ont passé plus de temps à emballer des choses telles que Linq To XML et des littéraux XML et à intégrer davantage d'opérateurs de requête dans la syntaxe ...