Shizuku Blog ~ techbank.jp版~

~女性エンジニア けろ-みおの苦悩~

ログイン | ID登録 | ヘルプ


ニュース


当Blogにについて

当Blogは、けろ-みおが備忘録として活用しているBlogになります。掲載している内容について、必ずしも正しい情報を公開しているわけではありませんので予めご了承下さい。
当Blogで公開している記事に対して、質問がある場合は、techbank.jp掲示板でお問い合わせ頂くか、techbank.jp ID申請を行い、IDを作成した段階で当Blogにコメントする等してください。
原則、正体がわからない方からのBlogコメント欄を使ったご質問・ご指摘は、承っておりません。
コメント投稿・公開(承認)基準につきましては、 当Blogのコメント投稿についてをご確認ください。
テクニカルコミュニティ(techbank.jp)に設置しているBlogということもあり、皆様のご理解とご協力の程、宜しくお願いします。

自己紹介

けろ-みおと申します。「techbank.jp」の副管理人をやっております。

MVP Profile

0







けろ-みおの関連サイト





このBlogの人気度
フィードメーター - techbank.jpコミュニティ

techbank.jp Blog全体と近いBlog
あわせて読みたいブログパーツ

このBlogと近いBlog
あわせて読みたいブログパーツ

Blog購読者数
スカウター : techbank.jp







VB.NET : VBにおける遅延評価と遅延実行

 

このお話は、Visual Basic 中学校の管理人である、るきおさんとマイクロソフトの小高さんとお話していた時に

出た話です。ちょっとまとめてみたいと思います。

あまり言語仕様系については、得意ではないのですが、実際プログラムを作っていると、今後は意識しなければならない

点も多いような気がしたので、勉強のために掲載しておきます。

 

問題点は、C#でいう、yield return に相当するものがVBにはないため、LINQの拡張メソッドを作っても、

評価のタイミング(ようは、遅延評価)が、できないというものです。(即時実行になってしまうというもの。)

 

るきおさんが作った検証コード

 

◆ C#版 (yield return使用)

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            var names = new string[] { "エリマキトカゲ", "イノシシ", "アメンボ", "ウマ", "オオカミ" };
 
            var query = names.FilteredLongHighPass().OrderBy(s=>s);
 
            MessageBox.Show("これからLINQを評価します。");
            MessageBox.Show(string.Join("\n", query.ToArray()));
        }
 
 
    }
 
    static class MyExtensions
    {
        public static IEnumerable<string> FilteredLongHighPass(this IEnumerable<string> values)
        {
            MessageBox.Show("拡張メソッドが呼ばれました!");
 
            foreach (var value in values)
            {
                if (value.Length >= 3)
                    yield return value;
            }
        }
 
    }

 

 

◆VB版

(yield returnは使用できないので、List(Of String) で代替えしたみたいです。

 それにしても拡張メソッドを作るのに、Moduleが相変わらず気に入らないや)

Public Class Form1
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 
        Dim names = New String() {"エリマキトカゲ", "イノシシ", "アメンボ", "ウマ", "オオカミ"}
 
        Dim query = names.FilteredLongHighPass.OrderBy(Function(name) name)
 
        MsgBox("これからLINQを評価します。")
 
        MsgBox(String.Join(vbNewLine, query.ToArray()))
 
    End Sub
 
End Class
 
Module Module1
 
    <System.Runtime.CompilerServices.Extension()> _
    Public Function FilteredLongHighPass(ByVal values As IEnumerable(Of String)) As IEnumerable(Of String)
 
        MsgBox("拡張メソッドが呼ばれました!")
 
        Dim results As New List(Of String)
 
        For Each value In values
            If Len(value) >= 3 Then
                results.Add(value)
            End If
        Next
 
        Return results
 
    End Function
 
 
End Module

 

遅延評価のタイミングは抜きにしても、C#では、実体の型に関係なく、Collectionを返せるのに対し、

VBでは、それができない。(VBの場合は、IEnumerableインターフェースを適用しているクラスを返さなければならない)

これは、yield return がVBにないからという最大の弱点ですね。

 

そして、下記にあるコードが私が手を加えたコードです。(VB側の拡張メソッドの箇所のみ手を加えた

 
Module ExtensionMethods
 
    <System.Runtime.CompilerServices.Extension()> _
    Public Function FilteredLongHighPass(ByVal values As IEnumerable(Of String)) As IEnumerable(Of String)
 
        MsgBox("拡張メソッドが呼ばれました!")
 
        Return values.Where(Function(value) value.Length >= 3)
 
    End Function
 
End Module

 

ま、見てわかるとおり、LINQ + ラムダ式を使って、実態の型を意識しないで、IEnumerableインターフェースでCollectionを

返すようにできる方法ではありますが、うーん、これで良いのかな?

yield return には若干近づいたとは思うんですけど、Collectionは、実態の型か?というと、答えは、「No」だと私は思います。

遅延実行か?というと、「Yes」だと個人的には思いますが・・・どうなんだろ?間違っていたらご指摘ください。

 

さらに、

http://msdn.microsoft.com/ja-jp/library/bb943859.aspx にもあるように、

Visual Basic 9.0 には、yield キーワードに相当するものがありません。
このため、この言語での遅延実行の実装はより複雑になります。

 

とあるので、やはり、VBを使って、遅延評価・遅延実行させるには、類似したものは複雑だとは言え、実装可能ではあるものの

C#のyield return とまったく同じものができるかというと、厳密には「できない」というべきなのかもしれません。

 

この辺り、こうすると良いというお答えわかる方、いらっしゃいましたら、私やるきおさん、小高さんに情報をお寄せ下さい。

ぷはー、やっぱり、言語仕様系にめっぽう弱い、けろでした・・・(ましてや、ラムダ式は更に苦手です・・・)

Published 2008年5月25日 17:12 けろ-みお

コメント

このBlogに対するコメントはありません

コメントを残す

(必須) 
(必須) 
(オプション)
(必須)