C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: メソッドの引数にプロパティを渡した時の挙動について


(過去ログ 19 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■7501 / inTopicNo.1)  メソッドの引数にプロパティを渡した時の挙動について
  
□投稿者/ 向井 (1回)-(2007/09/07(Fri) 11:16:14)

分類:[VB.NET/VB2005] 

2007/09/07(Fri) 11:18:43 編集(投稿者)

はじめまして。向井と申します。

あるクラスのメソッドを呼び出す際、
メソッドの引数にプロパティを渡して呼び出した場合、
メソッドが実行された後に、引数で渡したプロパティの
setがなぜか呼ばれます。

これは.NETのバグなのでしょうか。
それとも何か初歩的な誤りをしているだけなのでしょうか。
皆目見当がつかず困っております。

■環境:
VB.NET 2.0
ASP.NET 2.0
Visual Studio 2005

■例:ClientクラスでClassAをNewし、ClassAのメソッドを呼び出します。
   この際、引数にClassAのPropプロパティを渡しています。
   すると、Methodメソッドが実行された後、PropプロパティのSetが呼び出されます。
   ステップ実行して頂くと、その動きが確認できます。
   ※なお、ClassAのメソッドを呼び出す際に、
    ClassAのプロパティを渡す必要はない、といったご指摘は無用です。
    登場するクラス数を最小限にしたかったので、このような例にしたまでです。
   
public class Client

public sub aaa()
Dim classA As New ClassA
classA.Method(classA.Prop)
end sub

end class

Public Class ClassA

Private prop_ As Integer

Public Property Prop() As Integer
Get
Return prop_
End Get
Set(ByVal value As Integer)
prop_ = value
End Set
End Property

Public Sub Method(ByRef arg As Integer)

End Sub

End Class

以上です。
どうかよろしくお願いします。

引用返信 編集キー/
■7502 / inTopicNo.2)  Re[1]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ とりこびと (31回)-(2007/09/07(Fri) 11:38:13)
とりこびと さんの Web サイト
No7501 (向井 さん) に返信
> 2007/09/07(Fri) 11:18:43 編集(投稿者)
> 
> はじめまして。向井と申します。
> 
> あるクラスのメソッドを呼び出す際、
> メソッドの引数にプロパティを渡して呼び出した場合、
> メソッドが実行された後に、引数で渡したプロパティの
> setがなぜか呼ばれます。
> 
> これは.NETのバグなのでしょうか。
> それとも何か初歩的な誤りをしているだけなのでしょうか。
> 皆目見当がつかず困っております。

バグではなく仕様です。メソッドへの渡し方によります。


Public Class ClassA

    Private prop_ As Integer

    Public Property Prop() As Integer
        Get
            Return prop_
        End Get
        Set(ByVal value As Integer)
            prop_ = value
        End Set
    End Property

    Public Sub ByRefMethod(ByRef arg As Integer)

    End Sub

    Public Sub ByValMethod(ByVal arg As Integer)

    End Sub

End Class


Public Class Program

    Public Shared Sub Main()

        Dim a As New ClassA

        a.ByRefMethod(a.Prop)

        a.ByValMethod(a.Prop)

    End Sub

End Class

引用返信 編集キー/
■7503 / inTopicNo.3)  Re[2]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ なちゃ (58回)-(2007/09/07(Fri) 11:43:04)
ByRefにした目的は?
引用返信 編集キー/
■7507 / inTopicNo.4)  Re[3]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ 囚人 (157回)-(2007/09/07(Fri) 12:01:55)
???

こんな構文 C# だとアウトなんですけど、どうなってるんでしょ??
引用返信 編集キー/
■7511 / inTopicNo.5)  Re[4]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ 向井 (2回)-(2007/09/07(Fri) 12:33:13)
ByRefが原因だったのですか。

MethodメソッドのargをByValに変更すると解決しました。
迅速なご回答に心から感謝します。

解決済にする前にもう少しだけ質問させてください。

なぜByRefだとこのような挙動になるのでしょうか。

因みに、ByRefにしていた理由は、メモリ節約のためです。
ByValだとコピーを作成するのですよね?
なので、自分は普段から特別な理由がない場合はすべてByRefで渡しています。
この考え方は一般的ではないのでしょうか。
ご教授ください。


引用返信 編集キー/
■7512 / inTopicNo.6)  Re[5]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ Hongliang (190回)-(2007/09/07(Fri) 12:56:40)
Hongliang さんの Web サイト
2007/09/07(Fri) 12:57:51 編集(投稿者)

No7511 (向井 さん) に返信
> なぜByRefだとこのような挙動になるのでしょうか。
プロパティの実体はメソッドの呼び出しです。
... = a.Value
は実際には
... = a.get_Value()
になりますし(メソッド名はこうなるとは限りませんが)、
a.Value = ...

a.set_Value(...)
になります。
これは ByRef では表現できません。ByRefMethod(a.get_Value()) としただけでは、ByRefMethod の先でもし get_Value() した値が書き換わってしまったときに書き出すことができませんし。
ですので、コンパイラは
... = a.get_Value()
ByRefMethod(...)
a.set_Value(...)
という感じに展開します。
// やーもう C# みたいに禁じてくれればいいんだけど。バグを生み出しかねないし。

> 因みに、ByRefにしていた理由は、メモリ節約のためです。
> ByValだとコピーを作成するのですよね?
> なので、自分は普段から特別な理由がない場合はすべてByRefで渡しています。
> この考え方は一般的ではないのでしょうか。
> ご教授ください。
一般的ではないですし、いくらか誤解があります。
ByVal/ByRef は値渡し/参照渡しと呼ばれます。
それに対し、Structure/Class で表現される値型/参照型という概念があります。
これらの組み合わせでなにがどうコピーされるのか調べてみるといいでしょう。
引用返信 編集キー/
■7514 / inTopicNo.7)  Re[6]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ 囚人 (158回)-(2007/09/07(Fri) 13:00:15)
超でかい構造体なら ByRef の方がましかもしれないですけど、効率の問題で言えば ByRef の方が逆に非効率じゃないかなと。


しかし、プロパティの参照渡しってかなり奇妙(つーか普通使わない)なのですが、VB にはトリックがあるようですね。初めて知りました。VB 凄いな。

引用返信 編集キー/
■7530 / inTopicNo.8)  Re[7]: メソッドの引数にプロパティを渡した時の挙動について
□投稿者/ 向井 (3回)-(2007/09/07(Fri) 14:24:50)
> ですので、コンパイラは
> ... = a.get_Value()
> ByRefMethod(...)
> a.set_Value(...)
> という感じに展開します。

なるほど。理解しました。

今後は、特別な理由がない限りByValにします。
メモリ節約の認識の誤りについては調べてみます。
stringやintegerが何者かよく理解していないんですね。
なぜnewしなくてもいいのか。

ご丁寧にご回答を頂き、ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -