Feeds:
投稿
コメント

Posts Tagged ‘VB.NET’

VB.NET 11の新機能を最近知ったなど

さて、Yieldってなんだって話からですがこれはC#には2.0の時くらいからすでにあるyield returnの機能です
Yieldでyield returnが実行されます。yield breakはなさそう

ちょっと少し話が前後しますが最初に戻して進めます

・VB.NET 11での新機能
http://msdn.microsoft.com/en-US/library/we86c8x2.aspxを参照にしながら

書いてあるのは次の通りですね
・Async/Await
・Iterator/Yield
・呼び出し階層
・メソッド情報
・Global Namespaceのサポート

簡単なのはGlobal Namespaceですかね。これは今までルート名前空間に強制的に所属させられていたVB.NETですがGlobalを最初につけることでルート名前空間をつけなくて済みます
つまりSystem.linqに新しくクラス追加しようと思ったときいちいちルート名前空間をSystemにしなくてもGlobal.System.linqにすればいいわけです

メソッド情報は引数に属性をつけることで引数として現在の実行メソッド情報をとれる…?やつなんですかねぇ。これは分かりません

呼び出し階層はスタックトレースみたいのが取れるんじゃないかなぁと

Async/Awaitは非同期待機のやつですね。いくらでも書いてありそうなのでここではスルー

さて、最後にIterator/Yieldですがこれは反復子を指しますIteratorで宣言された関数はReturnの代わりにYieldで返す必要があります

・Iterator/Yield
ちゃんと見ていきます

[accessmodifier] Iterator (Function|Property)の戻り値はIEnumerable(Of T)またはIEnumerator(Of T)となります。(?) 
またYieldは遅延実行することを示します。

Yieldは主にLINQで使われてたりするものです。つまるところ必要になるまでメソッドは実行されずに必要になったら評価されて実行されます。
少しコードを書いて試してみましょう

・yield returnの実行順序
次のようなソースコードを用意します。コンソールアプリケーションです

Private Iterator Function GetIterator(xcol As String) As IEnumerable(Of Char)
    For Each xch In xcol
        Yield xch
        Console.WriteLine("validation value")
    Next
End Function

Sub Main()
    Dim testArgs As IEnumerable(Of Char) = GetIterator("abcdefghijklmnopqr")
    For Each x In testArgs
        Console.WriteLine(x)
    Next
    Console.WriteLine("end test")
End Sub

この実行結果は次の通りです

画像のとおり、yieldでリターンするとYield句まできた時点でメソッドはブロックされ、元の処理に戻されます。
そのためYieldの下のブロックは戻ってきたときにふたたび次のYieldまで実行されます

そのため上の画像のようにFor Each中に値の評価を行います。For Eachしたからといってすべてが一斉に返されないのも特徴といえるかもしれません

・Whereを実装してみる
yield return知りたいならLINQのWhereとか実装するといいといわれたので

自分でVB.NETでWhereを実装すると次のような感じです

Private Iterator Function myWhere(Of T)(source As IEnumerable(Of T), predicate As Func(Of T, Boolean)) As IEnumerable(Of T)
    For Each x As T In source
        If predicate(x) Then Yield x
    Next
End Function

これで次のようなコードを実行してみます

Sub Main()
    Dim testArgs As IEnumerable(Of Integer) = Enumerable.Range(1, 200)
    For Each i In myWhere(testArgs, Function(x) x Mod 5 = 0)
        Console.WriteLine(i)
    Next
    Console.WriteLine("end test")
End Sub

実行結果は…まあ普通のWhereの結果です

Selectは次のような感じでいいのかな?(テストできてない)

Private Iterator Function mySelect(Of T, TValue)(source As IEnumerable(Of T), predicate As Func(Of T, TValue)) As IEnumerable(Of TValue)
    For Each x As T In source
        Yield predicate(x)
    Next
End Function

・どこで使うの
まあ基本はLINQみたいにコレクション操作になるとは思いますがYieldでやる必要がありなおかつLINQでサポートされてないメソッドというのがそんなにたくさん出てくるのか微妙な気は
そもそも.NET Framework 4.5なのでLINQでサポートしてる内容をわざわざYieldで使う必要ってないんですよね

LINQの理解のために使うとかLINQわからないからYield… くらい…?
それよりはやっぱりLINQとかでサポートしてないやつになるかなぁ…


結局使用方法が見いだせず…
というか前半の文面なんも考えてなかったせいでわかりづらいですね

とりあえずこの辺で

広告

Read Full Post »