- - PR -
参照型におけるByRef ByValについて
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-07-25 13:55
現在、VisualStudio2005 VBを用いているのですが、
参照型の場合の引数において、 ByRefを使うべきかByValを使うべきなのかがわかりません。 質問前に調べたところ、以下のような解説がありました。 http://www.microsoft.com/japan/msdn/net/vbnetref/vbnetref3-6.aspx http://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet11/vb6tonet11_01.html 上記microsoftさんのサイトから引用します。 ---------------------------------------------- 1: Private Sub Button1_Click(ByVal sender As System.Object, ... 2: Dim X As Integer = 1000 3: Dim MyArr() As Integer = {700, 800, 900} 4: F2(X, MyArr) 5: End Sub 6: 7: Private Sub F2(ByVal A As Integer, ByVal Dat() As Integer) 8: MsgBox(A) 9: MsgBox(Dat(0)) 10: End Sub ここで7行目において、ByRefとした場合とByValにした場合でどのように 変わってくるのでしょうか? ByRefは参照情報をコピーすると思っているのですが、 ByValにおいても参照情報をコピーすると解説されております。 一般的には、このような場合はByValとByRefどちらを使うべきなのでしょうか? | ||||||||||||
|
投稿日時: 2008-07-25 14:11
普通はByValでByRefを使うことはないでしょう。
ByRefの場合、オブジェクトそのものを変更することが可能です。 例えばClassAとそれを継承したClassBがあったとして メソッド側でクラス参照そのものを書き換えることができます。 メソッドを使う側としては、かってにインスタンスを変えられたら怖いですよね? これは極端な例ですがで、特に理由が無いかぎりByValを使うべきです。
[ メッセージ編集済み 編集者: burton999 編集日時 2008-07-25 14:12 ] | ||||||||||||
|
投稿日時: 2008-07-25 15:35
わかりやすい返答ありがとうございます。
返答内容を参考に、継承したクラスを用いてテストしてみました。 参照型においても、ByValとByRefで動作が違いを確認することができました。 Cのポインタと、値渡し的な概念(VB6までのByValとByRef)でしか 理解していなかったので助かります。 >これは極端な例ですがで、 このように書いてあるように、例のケースというのは、 よほどのコーディング(もしくは設計)ミスでしか起きないのではないか? とも思います。 (フェールセーフとなるため、基本はByValを使用するようにします) では逆に、参照型の変数を引数とする場合でByRefを用いるケースというのは、 どのような場合が考えられるのでしょうか? | ||||||||||||
|
投稿日時: 2008-07-25 16:01
C のポインタというか参照ですね。 「値型」 と 「参照型」 それに加え 「値渡し」 と 「参照渡し」 の 4 通りがあるという理解があれば問題ないでしょう。 > ByRefは参照情報をコピーすると思っているのですが、 参照情報というか、'参照' ですが、これはむしろ 「しない」 という理解で良いですね。
ないと思います。 少なくとも私は実験以外で使用したことがありません。 値型なら BCL にも System.Double.Parse(String, <OutAttribute> Double) メソッドなどがありますが参照型のパターンは知らないですね。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||
|
投稿日時: 2008-07-25 20:22
無理やり挙げるなら、返す値が多くて引数にするしかなかったという場合でしょうか。 Sub Func1(ByVal p1 As Integer, ByRef obj As Class1) As enumResult いわゆるもらうだけというパターンですかね。 と言いつつ、この場合も全項目を持つ型を返すようにするほうが多いかな? まぁ実際にこの形が候補として挙がることすら無いと言ってよいでしょう。 参照型ではありませんがイメージ的には、Int32.TryParseメソッドを見てみるとよいでしょう。 #↑かぶってやんの。。。 [ メッセージ編集済み 編集者: まどか 編集日時 2008-07-25 20:25 ] | ||||||||||||
|
投稿日時: 2008-07-26 14:55
この場合もByValでいいと思うのですが・・・
| ||||||||||||
|
投稿日時: 2008-07-26 22:27
メンバの更新ではなくインスタンスを返す場合です。
| ||||||||||||
|
投稿日時: 2008-07-26 23:35
Dictionary<TKey, TValue> クラスの TryGetValue はありますね。
|