yield
in
vb.net
问题就在这里。
Caliburn
最近。很多很棒的东西,包括
co-routines
small MVVM framework
.
一切看起来都很好,除了使用VB的co例程。由于使用了vb10,我们可以尝试
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
我只是不明白下面这种稍微复杂一点的协同例程方法(取自Rob的游戏库)是如何用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();
}
你知道如何实现这一点吗?或者你对在VB中使用Caliburn co例程有什么想法吗?
编辑:
Marco
给我指出了一个正确的方向。在查看了Rob游戏库的Reflector-Visual Basic代码后,我成功地修改了Bill McCarthy的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版本那么优雅,但看起来是可行的。我们看看这个有没有问题。如果有人有更好的主意,我洗耳恭听。