2008-10-15 9 views
19

Je crois que le code VB.Net suivant est l'équivalent du code C# en cours; Cependant, le test VB.Net échoue - la gestion des événements Lambda n'est jamais appelée.Comment déclarer les gestionnaires d'événements lambda dans VB.Net?

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 

C# Version - 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(); 
     } 
    } 

Répondre

16

Note: Ce concerne les anciennes versions de VB.net Avant Visual Studio 2010 et VB.net 10

La différence est Dans VB.Net, une expression lambda doit renvoyer une valeur, c'est-à-dire qu'elle doit être une fonction et non un sous-ensemble. L'expression lambda eventRaised = true est interprétée comme une expression booléenne plutôt que comme une affectation, c'est-à-dire que l'évaluation est fausse plutôt que d'être vraie.

Plus de détails sur MSDN.

Je ne pense pas que le motif C# pour tester les événements utilisés dans l'exemple puisse être fait dans VB.Net sans introduire une autre fonction, par ex.

<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 
+14

Ils ont vraiment screawed avec lambdas dans VB.Net. – chrissie1

+0

D'accord, il semble qu'ils ont fait le minimum pour obtenir le lien en cours et c'est tout. –

+4

Notez qu'à partir de VS2010, les lambdas VB.Net peuvent maintenant être des sous-programmes et n'ont pas besoin de retourner une valeur. –

2

Longue histoire courte, vous ne pouvez pas le faire en VB pour le moment (il est sur la liste des fonctionnalités envisagé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 (ce que vous essayez d'utiliser, techniquement pas une expression lambda).

Les expressions Lambda ont dû être implémentées pour que Linq puisse réellement fonctionner. Les délégués anonymes ne sont requis par rien (mais seraient très utiles). Je pense qu'ils ont passé plus de temps à envelopper des choses comme Linq To XML et XML et à intégrer davantage d'opérateurs de requête dans la syntaxe ...

+0

Compris qu'il s'agit d'un délégué anonyme et non d'une expression lambda. Cependant, est ce qui suit (qui fonctionne) un délégué anonyme dans VB?: AddHandler eventClass.AnEvent, Function() (SetValueToTrue (eventRaised)) –

15

Pour ceux qui trouvent cette question maintenant: depuis Visual Basic 2010 (VB 10.0), anonyme Sub s fonctionnent, donc vous pouvez écrire quelque chose comme:

Sub() eventRaised = True 
+0

Et si plus d'une instruction suit Sub()? –

+1

@LeiYang Ensuite, vous pouvez faire: 'Sub() déclaration1 déclaration2 End Sub' (il s'agit de quatre lignes). – svick