Обратите внимание, что мне известны другие yield в vb.net вопросов здесь на SO.
Я играю с Caliburn в последнее время. Там куча отличных вещей, включая сопрограммы реализация.
Большая часть работы, которую я выполняю, основана на C #, но сейчас я также создаю руководство по архитектуре для магазина, предназначенного только для VB.NET, на основе небольшой инфраструктуры MVVM Роба .
Все выглядит очень хорошо, за исключением использования сопрограмм от VB. Поскольку используется VB 10, мы можем попробовать что-то вроде предложение Билла Маккарти :
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
Я просто не понимаю, как можно написать немного более сложный метод совместной работы, подобный приведенному ниже (взят из Rob's GameLibrary):
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();
}
Есть идеи, как этого добиться, или есть мысли по поводу использования сопрограмм Caliburn в VB?
Edit:
Марко указал мне правильное направление. Изучив код Reflector - Visual Basic в GameLibrary Роба, мне удалось изменить GenericIterator Билла Маккарти, чтобы он стал машиной состояния бедного человека:
Private _state As Integer = -1
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
_state += 1
Return _func(_Current, _state)
End Function
И мы можем использовать это так:
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
Это определенно не так элегантно, как в версии C #, но выглядит вполне выполнимо. Посмотрим, есть ли проблемы с этим. Если у кого-то есть идея получше, я весь в ушах.