Note that I know other yield in vb.net here on SO.
Recently, I play with Caliburn . A bunch of great things, including a joint subroutine .
Most of the work I do is based on C #, but now I am also creating an architecture guide for the VB.NET Rob-based store, a small MVVM framework .
Everything looks very good, except for using shared procedures from VB. Since VB 10 is used, we can try something like Bill McCarthy's suggestion :
Public Function Lines(ByVal rdr as TextReader) As IEnumerable(Of String) Return New GenericIterator(Of String) (Function(ByRef nextItem As String) As Boolean nextItem = rdr.ReadLine Return nextItem IsNot Nothing End Function) End Function
I just donโt understand how a slightly more complex collaboration method like the one below (taken from Rob GameLibrary) can be written in VB:
public IEnumerable<IResult> ExecuteSearch() { var search = new SearchGames { SearchText = SearchText }.AsResult(); yield return Show.Busy(); yield return search; var resultCount = search.Response.Count(); if (resultCount == 0) SearchResults = _noResults.WithTitle(SearchText); else if (resultCount == 1 && search.Response.First().Title == SearchText) { var getGame = new GetGame { Id = search.Response.First().Id }.AsResult(); yield return getGame; yield return Show.Screen<ExploreGameViewModel>() .Configured(x => x.WithGame(getGame.Response)); } else SearchResults = _results.With(search.Response); yield return Show.NotBusy(); }
Any idea how to achieve this, or any thoughts on using Caliburn's collaborative procedures in VB?
Edit:
Marco pointed me in the right direction. Having looked at Rob GameLibrary code in Reflector - Visual Basic, I managed to modify Bill McCarthy's GenericIterator to become an unmanageable person:
Private _state As Integer = -1 Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext _state += 1 Return _func(_Current, _state) End Function
And we can use it as follows:
Public Function ExecuteSearch() As IEnumerable(Of String) ' If we need some variable shared across states, define it here Dim someSharedStuff As String = String.Empty ' Notice the second lambda function parameter below - state Return New GenericIterator(Of IResult) (Function(ByRef nextItem As IResult, state As Integer) As Boolean Select Case state Case 0 someSharedStuff = "First state" nextItem = Show.Busy Return True Case 1 nextItem = Show.SomeLoadingScreen ' Do some additional processing here... Return True Case 2 ' Do something with someSharedStuff variable... Console.WriteLine(someSharedStuff) nextItem = PerforSomemWebServiceCall() Return True '... Case 6 nextItem = Show.NotBusy Return False End Select Return False End Function) End Function
It's definitely not as elegant as the C # version, but it looks doable. We will see if there are problems with this. If someone has a better idea, I'm all ears.