|
|
連載:放課後VB教室
第2回 文字列型の変数とチーズ大福
羽山 博
2008/07/11 |
 |
|
StringクラスとStringBuilderクラスの違い
同じ文字列を参照する文字列型の変数が2つあるとしよう。つまり、さっき見たコードと同じような場合を考えればいい。
Dim MyName As String = "ラスク"
Dim YourName As String
YourName = MyName
|
|
この後、さらに次のようなコードを実行するとどうなるだろう。
さすがに、もう間違えませんよ。MyNameの参照する文字列が「ネスト」になるから、同じ文字列を参照するYourNameも「ネスト」だなんてことはもういいません。新しく「ネスト」という文字列が作られるから、MyNameは「ネスト」を参照して、YourNameはこれまでどおり「ラスク」を参照します。

|
図6 同じ文字列を参照していた変数の一方に別の文字列を代入する |
|
そうだね。そのとおり。ところでこの動きって、ちょっと見た感じ、値型っぽくないかな? いや、値型っぽいとか参照型っぽいというのはあまり意味がないんだけど、「値型だからこうなる」とか「参照型だからこうなる」というとらえ方をしていると落とし穴に落ちる危険があるってことをいいたいんだ。
つまり、どういうこと?
参照型の場合、参照先の内容を変更すると、そのデータを参照しているすべての変数で、内容が変わったように見えるよね。
例えば、文字列型つまりStringクラスと似たものに、StringBuilderクラスというのがある。StringBuilderクラスでは文字列の内容が直接変更できるようになってるんだ。ちょっと例を見てみよう。さっきの例と比べられるように、できるだけ似たコードを書いてみるね。
Imports System.Text ' StringBuilderクラスを使うために必要な記述
:
:
Dim MyName As StringBuilder = New StringBuilder("ラスク")
Dim YourName As StringBuilder
YourName = MyName
MyName.Replace("ラスク", "ネスト")
Debug.Print(YourName.ToString())
|
|
Replaceメソッドは指定した文字列の一部を別の文字列で置換するためのメソッドで、最初の引数で指定した文字列を、2番目に指定した文字列に置き換えてくれる。
StringBuilderクラスは文字列の内容が直接変更できるから、MyNameで参照される文字列が「ラスク」から「ネスト」に変わる。この場合、YourNameはMyNameと同じ文字列を参照しているから、YourNameを参照しても「ネスト」になる。だから、最後のDebug.Printメソッドによって出力ウィンドウに表示される文字列は「ネスト」となる。動作のイメージは次のような感じだね。

|
図7 同じオブジェクトを参照している変数の一方から内容を変更する |
|
YourNameに関しては何もしていないけれど、MyNameの参照先の内容を変えたから、YourNameから参照される値も変わるよね。「参照型」というと、こういう感じの動きが典型的だから、参照型の場合、必ずこうなると思ってしまう人が多いみたいだけど、そうとも限らないってわけ。まあ、Stringクラスがちょっと特殊なんだけど。でも、よく使うだけに気を付けないといけない。
Dim MyName As String = "ラスク"
Dim YourName As String
YourName = MyName
MyName = "ネスト"
|
|
Dim i As Integer = 100
Dim j As Integer
j = i
i = 200
|
|
この2つのコードを見てごらん。文字列の場合MyNameに何を代入しようが、YourNameには影響しないよね。仕組みは全然違うけど、表面的な動きは値型と同じように見える。ほら、2番目のコードだとiに何を入れようがjには影響しないでしょ。
そっかー。「参照型の場合、内容を変更すると全部変わっちゃう」みたいに、いいかげんに暗記しているだけだと、一見矛盾するようなことにぶつかると混乱してしまうってことなんだ。
そう。おかしいな、と思ったときには仕組みまで踏み込んで考えてみるといいね。ちなみに、StringクラスにもReplaceメソッドがあって、文字列の一部を置換できる。でも、StringクラスのReplaceメソッドは、置換された文字列を返すだけで、元の文字列が参照している内容は変わらない。つまり、
Dim MyName As String = "ラスク"
MyName.Replace("ラスク", "ネスト")
|
|
としても、StringBuilderクラスと違って、MyNameが参照している文字列は変わらない。このReplaceメソッドでは単に置換された結果が返されるだけだから、MyNameが参照している文字列を変えようとすると、
MyName = MyName.Replace("ラスク","ネスト")
|
|
と書く必要がある。
へぇー、あ、いや、なんでやねん!
だから、そこはツッコむところじゃないって。ま、今日はこのへんにして、たこ焼きの屋台に行こうか。確か、クロワッサン先生がたこ焼き屋さんをやってたはず……。

わーい。
(つづく)
ラスクちゃんのまとめコーナー
- String型の変数に文字列を代入すると、その文字列は変更できなくなります。
- String型の文字列を変更すると、実際には新しい文字列が作成されます。
- StringBuilderクラスでは、Replaceメソッドなどを利用して、文字列の内容を直接変更できます。
|
|
|

|
次回もよろしくね。
業務アプリInsider 記事ランキング
本日
月間