• 締切済み

VB.NETで値や参照について ByRefなど

VB.NETで値や参照について、まだ初学ですがよろしくお願いします。 VBは2008です。 以下のようなs文字列を参照引数にしたSetDataメソッドがあります。 ByRef s As Stringという引数は、SetData内でsを書き換えると、 呼び出したSetDataメソッド外でも中身が変わるので 私のByRefの認識ではポインタと解釈しています。間違っているでしょうか? SetData(1,1, buf)とすれば、DataGridViewの中は、「初期値」という文字が表示されます。 別のメソッド(KaKikae)でbufを"あ"という文字に変えた場合、SetDataメソッドを使わなくても 書き換わっていると思っていたのですが、実際実行してみると書き換わりません。 値や参照について理解が足りないからだと思いますがわかりません。 どのようにすれば、それが実現できるのでしょうか? Public Class HogeClass Private buf As String = "初期値" Private Sub SetData(ByVal x As Integer, ByVal y As Integer, ByRef s As String) As Boolean Dim dg As DataGridView dg = DataGridView1 dg.Item(x, y).value = s End Sub Private Sub KaKikae() buf = "あ" End Sub End Class

みんなの回答

  • nas02
  • ベストアンサー率70% (22/31)
回答No.4

初心者の方が間違った知識を植えつけられるといけないので訂正しておきます。 以下のマイクロソフトのサイトにあるように、Stringクラスは参照型に分類されます。 http://msdn.microsoft.com/ja-jp/library/t63sy5hs.aspx なので狙い所はそう悪くありませんが、Stringクラスの文字列は変更不可です。 一度作成したら、通常は中身を直接書き換える事は出来ません。 別の文字列と入れ替える事はできますがポインタが変わりますので意図する所ではないですよね? 中身を書き換えたいのであれば、StringBuilderクラスを使いましょう。 ただ、これは勉強のためにやっている事ですよね? 一般的には、データグリッドの方を再設定します。 【補足】 強制的にStringクラスの文字列の一部を書き換え、データグリッドを再描画させると内容が変わる事は確認しました。 勿論、VB.NETではポインタが使えなくて無理なのでC#で確認してます。 また、StringBuilderクラスに置き換えてやってみると、tobasuさんが期待した通りの結果となりました。(VB.NET,C#)

  • AKARI0418
  • ベストアンサー率67% (112/166)
回答No.3

.NET系の言語には、 実数型の型とクラスのようにボックス化される型の2種類が存在します。 string型は実数型になるため、代入などはすべて実態のコピーを渡すようになっています。 一方で、クラスなどはボックス化されているため、その参照(ポインタ)が渡されます。 さて、ByRefやByvalは実数型の引数についてのみ意味があります。 ボックス化されているクラスを引数にして渡す場合、値渡しにしても、すでにポインタとして扱っているため、参照渡しをしているのと同じ結果になります。 問題の今回の場合です。 参照渡しした実数型の値を代入しているのだから、当然ポインタが設定されるのでは?? ということですよね? 答えは 渡されるのはその値のコピーです。 なぜかというと、受け取り側のvalueプロパティですが、これは実数型のstringです、ここにポインタをセットすることはできません。 しつこいようですが実数型だからです。 代入できないので、sの実態がコピーして渡されます。

回答No.2

DataGridViewに設定されるのは、ポインタではなく値です。 dg.Item(x, y).value = s ここで代入されるのはsのポインタではなく「sのポインタが示す値」。つまりsのコピーになるので、sを書き換えてもGridViewの中身は書き換わりません。 「ByRef = ポインタ渡し」という認識は間違っていませんが、あまり意識しすぎると今回のようにハマります。

回答No.1

乗っているコードは中途半端ではありませんか? メソッドのみの切り出しだけで呼び出し元のコードが無いように見えます。 サンプルでByValとByRefの違いをわかるようにしたコードを載せておきます。 テストコードなので例外処理などは全て省いてあります。 ------------------------------------------------------------------ Private Sub MainTest() Dim strData As String Dim blnRet As Boolean strData = "Nothing" blnRet = False '初期状態を表示 Debug.Print(strData + ":" + blnRet.ToString) blnRet = ByValTest(strData) 'ByValの結果を表示 Debug.Print(strData + ":" + blnRet.ToString) '初期化 strData = "Nothing" blnRet = False blnRet = ByRefTest(strData) 'ByRefの結果を表示 Debug.Print(strData + ":" + blnRet.ToString) End Sub 'ByValテスト(値渡し) Private Function ByValTest(ByVal strBuf As String) As Boolean strBuf = "ByVal" Return True End Function 'ByRefテスト(参照渡し) Private Function ByRefTest(ByRef strBuf As String) As Boolean strBuf = "ByRef" Return True End Function ------------------------------------------------------------------ ※これでもわかりにくいようであれば参考URLをご覧下さい。

参考URL:
http://homepage1.nifty.com/CavalierLab/lab/vb/byvalbyref.html

関連するQ&A