連載:放課後VB教室

第2回 文字列型の変数とチーズ大福

羽山 博
2008/07/11
Page1 Page2

StringクラスとStringBuilderクラスの違い

同じ文字列を参照する文字列型の変数が2つあるとしよう。つまり、さっき見たコードと同じような場合を考えればいい。


Dim MyName As String = "ラスク"
Dim YourName As String
YourName = MyName

 この後、さらに次のようなコードを実行するとどうなるだろう。


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メソッドなどを利用して、文字列の内容を直接変更できます。

 


次回もよろしくね。End of Article

 

 INDEX
  放課後VB教室
  第2回 文字列型の変数とチーズ大福
    1.文字列型の変数は値が変更できない?
  2.StringクラスとStringBuilderクラスの違い
 
インデックス・ページヘ  「放課後VB教室」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH