2008-10-15 6 views
19

다음 VB.Net 코드는 진행중인 C# 코드와 동일하다고 생각합니다. 그러나 VB.Net 테스트는 실패합니다. Lambda를 호출하는 이벤트는 호출되지 않습니다.VB.Net에서 람다 이벤트 처리기를 선언하는 방법?

무슨 일입니까?

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

답변

16

참고 :이 VB.net의 이전 버전에 관한 이전의 Visual Studio 2010을 및 VB.net 10

차이점은 VB.Net에서 람다 표현식은 값을 반환해야합니다. 즉, 함수는 서브가 아닌 함수 여야합니다. 람다 식 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 
+14

그들은 VB.Net에서 lambdas로 정말 멋지게 꾸며 냈습니다. – chrissie1

+0

동의, 그들은 링크가 가고 최소한의 것 같았어요. –

+4

VS2010 현재 VB.Net 람다는 서브 루틴이 될 수 있으므로 값을 반환 할 필요가 없습니다. –

2

길고도 짧은 이야기, 당신은 시간이되고 (이것은 다음 릴리스 간주 기능의 목록에)에 대한 VB에서 그렇게 할 수 없습니다. 선언 된 메서드와 AddressOf 연산자를 사용해야합니다.

비주얼 베이직 팀은 익명 (사용하려고하는 무엇, 기술적으로 람다 표현식) 언어의 대표를 포함 할 시간이 없었다.

Linq가 실제로 작동 할 수 있도록 구현해야하는 Lambda 식. 익명의 위임자는 아무 것도 요구하지 않습니다 (그러나 매우 유용 할 것입니다). Linq To XML 및 XML litterals와 같은 것들을 마무리하고 구문에 더 많은 쿼리 연산자를 통합하는 데 더 많은 시간을 소비했다고 생각합니다 ...

+0

이 익명의 대리인이 아닌 람다 식임을 이해했다. VB에서는 다음과 같은 익명의 대리자가 작동합니까? AddHandler eventClass.AnEvent, Function() (SetValueToTrue (eventRaised)) –

15

Visual Basic 2010 (VB 10.0) 이후 익명의 Sub s는 일을하므로 다음과 같이 쓸 수 있습니다 :

Sub() eventRaised = True 
+0

둘 이상의 명령문이 Sub()를 따를 경우 어떻게됩니까? –

+1

@LeiYang 그럼 당신은 할 수 있습니다 :'서브() 문장 1 문장 2 종료 Sub'를 (이 네 줄입니다). – svick