« 2011年4月 | トップページ | 2012年6月 »

2011年5月15日 (日)

Split考

■2つのSplit

文字列を区切ってくれる便利なSplitメソッドには実は2種類あって、1つがStrings.Split, もう1つがString.Splitです。(紛らわしいですがスペル的にはStringが複数形か単数形かの違いです。)

VBではStringsモジュールは省略可能なので、Strings.Splitを使っている人は普段は単にSplitと書いていて、Stringsモジュールを使っていることを意識していないことと思います。

それぞれの例

Strings.Splitの例

Dim value As String = "A,B,C"
Dim items() As String = Split(value, ",")

String.Splitメソッドの例

Dim value As String = "A,B,C"
Dim items() As String = value.Split(",")

■それぞれの違い

で、このどちらを使うかですが、昔何か面倒なことがあって私はずっとStrings.Splitの方を使っています。

ところが時が経つにつれて「何か面倒なこと」の内容を忘れてしまい、最近は「何でこっちがいいんだったろうか?」などと思いながらプログラムする日々が続いていました。

それを久しぶりに思い出したのでブログに書いておきます。知っている人にはつまらない話だと思います。

実はString.Splitはそのままでは区切り文字を1文字しか指定できないのに対し、Strings.Splitの方は何文字でも指定でき、区切り文字が2文字以上の時の書き方に差が出るのです。

どういうことかというと、

まず、Strings.Splitで区切り文字が2文字の場合、

Dim value As String = "AXYBXYC"
Dim items() As String = Split(value, "XY")

これは結果は "A", "B", "C"になります。

ところが、

同じことをそのままString.Splitで書くと、

Dim value As String = "AXYBXYC"
Dim items() As String = value.Split("XY")

これの結果は "A", "YB", "YC"になります。

String.Splitの方でこのような書き方をすると先頭の1文字だけ(上の例だと"X"だけ)を区切り文字として扱い、2文字目以降は無視されるのです。

■違いの理由

これは、上記のString.Splitの第1引数はChar型であって、String型でないことによります。"XY"はString型なので、上のような呼び出しを行うとChar型に自動的に変換されます。ところがChar型は1文字しか表せない方なので"X"だけが採用されるのです。

String.Splitを使って複数文字の区切り文字を扱いたい場合、文字列型ではなく、文字列型の配列にするとうまくいきます。

次のように書きます。

Dim value As String = "AXYBXYC"
Dim items() As String = value.Split({"XY"}, StringSplitOptions.None)

多分、これが面倒で統一的な書き方ができるStrings.Splitを私は使い続けていたのでしょう。

なお、Option Strict Onの状態ではvalue.Split("XY")はそもそもエラーになって実行できません。

■補足

ついでに念のため補足。Option Strict Onの状態だとこれもエラーにされます。

Dim items() As String = value.Split(",")

これを解決する一番簡単な方法は次のように書くことです。

Dim items() As String= value.Split(","c)

| | コメント (1) | トラックバック (0)

2011年5月 8日 (日)

さようなら、ByVal

2011年3月にVisual Studio 2010 SP1では、いくつかの機能追加と変更、バグの修正が行われています。

http://support.microsoft.com/kb/983509/ja

この中で、見落としていたのですがVBでプロシージャを作ると自動的にパラメーターの前につくByValが自動ではつかなくなったのをご存じだったでしょうか?

私は最近気が付きました。

■具体例

たとえば、

private sub test (x as integer)

と書いて、[Enter]キーを押すと、従来は次のようにXの前にByValが自動的に付きました。

Private Sub test(ByVal x As Integer)

それがSP1を入れると大文字小文字が変換される以外特に変化なしです。

Private Sub test(x As Integer)

xの前に何も書かなかった場合、ByValと同じ意味になりますので機能上の変更はないです。

イベントプロシージャでも変わりました。フォームをダブルクリックすると従来は次のコードが生成されていました。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

SP1を入れるとこうなります。

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

■変更の背景

このことは上にあげたリンク先の変更点の一覧にも書いてあります。

さらにそこからリンクをたどっていくともとはユーザーからの提案だったようです。

https://connect.microsoft.com/VisualStudio/feedback/details/542271#details

引用

>At this point, repeating ByVal everywhere is just noise.

私訳:こうやって見ると、どこにでもいちいちByValってでるのはうざいです。

■Visual Basic 開発チームへの提案は誰でもできる

日本語でも提案をすることはできますので、普段思っていることがある方は提案してくださいね。(VB中学校よりもレベルは高いので、「こんなこと提案していいのかな」と思ったらまずはVB中学校掲示板で相談してみて下さい。)

マイクロソフトへの提案サイト(日本語版。バグ報告もあり。)

https://connect.microsoft.com/VisualStudioJapan/Feedback

Visual Basic中学校掲示板

http://rucio.cloudapp.net/ThreadList.aspx

| | コメント (0) | トラックバック (0)

« 2011年4月 | トップページ | 2012年6月 »