6

SOに関するvb.netの質問で他の収量 認識していることに注意してください。

最近はカリバーンで遊んでいます。コルーチンの実装など、素晴らしいものがたくさんあります。

私が行っている作業のほとんどは C# ベースですが、現在、Rob の小さな MVVM フレームワークに基づいて、VB.NET のみのショップ向けのアーキテクチャ ガイドラインも作成しています。

VB のコルーチンを使用することを除いて、すべてが非常によく見えます。VB 10 が使用されているため、Bill McCarthy の提案のようなものを試すことができます。

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 の GameLibrary から取得) を 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コルーチンを使用することについての考えはありますか?


編集:

マルコは私に正しい方向を示しました。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# バージョンほどエレガントではありませんが、実行可能に見えます。これに問題があるかどうかを確認します。誰かがより良い考えを持っているなら、私はすべての耳です。

4

1 に答える 1

3

私が理解している限り、VBの回避策は、さまざまなステップの均一性に依存しています。つまり、終了条件が満たされるまで同じアクションを繰り返します。

代わりに、Caliburnコルーチンは、反対のシナリオで役立ちます。制御コードとインターレースされた不均一な(および非同期の)ステップ。しかし、これは基本的にステートマシンです。

実際、CaliburnはC#コンパイラを利用して、無料で自動的に生成されたステートマシンの実装を取得します。したがって、解決策は、C#コンパイラによって構築されたものと同じように単純な手作りのステートマシンを構築することかもしれません(http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iteratorsを参照)。 aspx)。

于 2010-03-27T16:06:10.503 に答える