c# - 有没有办法在 VB.NET 中实现类似 Caliburn 的协程,因为没有 yield 关键字

标签 c# vb.net yield coroutine caliburn

请注意,我知道其他 yield in vb.net关于 SO 的问题。

我正在玩弄 Caliburn最近。那里有很多很棒的东西,包括 co-routines实现。

我正在做的大部分工作都是基于 C# 的,但现在我还基于 Rob 的 small MVVM framework 为仅使用 VB.NET 的商店创建架构指南。 .

除了使用 VB 中的协程外,一切看起来都很好。由于使用了 VB 10,我们可以尝试类似 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

我只是无法理解如何用 VB 编写更复杂的协程方法,例如下面的方法(取自 Rob 的 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();
}

知道如何实现这一点,或者对在 VB 中使用 Caliburn 协程有任何想法吗?


编辑:

Marco给我指明了正确的方向。在查看 Reflector - Rob 的 GameLibrary 的 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# 版本优雅,但它看起来是可行的。我们会看看这是否有任何问题。如果有人有更好的主意,我会洗耳恭听。

最佳答案

据我所知,VB 解决方法依赖于各个步骤的一致性;换句话说,它会重复相同的操作,直到满足退出条件。

相反,Caliburn 协同例程在相反的场景中很有用:非均匀(和异步)步骤与控制代码交错;但这基本上是一个状态机。

实际上,Caliburn 利用 C# 编译器获得一个免费且自动生成的状态机实现;所以解决方案可能是构建一个简单的手工状态机,就像 C# 编译器构建的状态机一样(参见 http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx)。

关于c# - 有没有办法在 VB.NET 中实现类似 Caliburn 的协程,因为没有 yield 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2526836/

相关文章:

javascript - 在 Javascript 中使用 vb.net 代码

java - 增加3个变量

c# - wpf:如何弹出用户控件?

c# - 返回值的方法不能传递给异常处理程序

c# - 在 emgucv 3.1 中绘制轮廓

c# - 如何告诉 Application Insights 忽略 404 响应

.net - 在自定义表单上添加 DesignerVerbs

vb.net - 如何为 wso2 安全 token 服务创建 .NET 客户端

python - Python中的yield表达式的结果是什么?

c# - VB.NET 中 "yield return"的等效语法是什么?