- PR -

引数: ref object について

投稿者投稿内容
Sakky
会議室デビュー日: 2005/02/22
投稿数: 2
投稿日時: 2005-02-22 10:57
お世話になります。
引数: ref object で任意の型の参照を渡すことは出来ないのでしょうか。
よろしくお願いします。
環境:VS2003.NET C# Win2000

main()
{
int a = 0;
Test( ref a );
}

private void Test( ref object a )
{
....
}

コンパイルエラーが出ます。↓
引数 '1' : 'ref int' から 'ref object' に変換できません。


C言語だとmemcpyなどvoid型のポインタを使って
任意の型を引数にした関数が作れましたが、
それと同等のことをやるにはどうしたらよろしいでしょうか。
よろしくお願い致します。
Fujiwo
常連さん
会議室デビュー日: 2002/02/19
投稿数: 20
投稿日時: 2005-02-22 11:22
# 直接の回答でなくてすみません。

確かにそれだとエラーになりますけれど、それがどういう用途で必要かによって代替案も変わってくるような気がします。

具体的な用途もあげて頂けると、ありがたいです。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-02-22 12:06
ふ〜む、VB.NETだと素直に参照渡しできるんですけどね〜

参照型に値を渡すためにはBoxingが必要になります。大抵はコンパイラが勝手にやってくれるので、意識する事は滅多にありません。ですがこの場合はBoxingせずに、エラーになるみたいですね。言語仕様の差なのかなぁ・・・。

↓とかすれば動くけど、やっぱり駄目なんだよね?
int a = 0;
object b = a;
Test( ref b );
_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2005-02-22 12:33
引用:

↓とかすれば動くけど、やっぱり駄目なんだよね?



大抵駄目だろうから、C# 的にはエラーにしている予感。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-02-22 15:28
参照渡しというのは、引数として指定した変数が指し示しているインスタンスを受け取るのではなくて、引数として指定した変数そのものを受け取るものです。例えば、
f(s);
とした場合はf()内で受け取るものはsが指し示しているインスタンスですが、
f(ref s);
とした場合はsそのものを受け取ります。ですので例えばAというクラスとそれを継承したBというクラスがあって、
 public class A{}
 public class B : A{}
以下のf()のようなメソッドがあった場合に
 public void f(ref A a){}
下の(1)や(2)のようなことは出来ませんよね。
 this.f(ref new A()); ・・・(1)
 B bi=new B();
 this.f(ref (A)bi); ・・・(2)

Sakkyさんの例でTest()の中で
a = new ArrayList();
とやったらどうなると思いますか?
main()に戻った時にint aはどういう値になっているべきだと思います?
そう考えるとできないということがはっきりしませんか。

[ メッセージ編集済み 編集者: 一郎 編集日時 2005-02-22 15:29 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-02-22 21:10
 オーバーロードします。
コード:
class Hoge {
	public void Test(ref int A) {
		...
	}
	public void Test(ref double A) {
		...
	}
	...
}


 「何でも受け付けます」というのは、一見便利ですが、バグの温床になります。仮想クラスやインタフェースで型指定するべきでしょう。


 あと、intを渡したいのでしょうか?それともテストとしてintにしたらエラーがでたのでしょうか?
コード:
class Hoge {
	public int A = 0;
}

main() {
	Hoge h = new Hoge();
	Test(h);
	h.A = 10;
	System.Diagnostics.Debug.WriteLine(h.A);
}

void Test(object O) {
	if (O is Hoge) {
		((Hoge) H).A = 100;
	}
}


このコードでは、h.Aは100になります。ただし、
コード:
void Test(object O) {
	O = new Hoge();
	if (O is Hoge) {
		((Hoge) H).A = 100;
	}
}


だと、10です。「値型」と「参照型」をキーに検索して、調べてください。

_________________
Sakky
会議室デビュー日: 2005/02/22
投稿数: 2
投稿日時: 2005-02-23 09:13
沢山回答を頂きましてありがとうございました。
ArrayList等を考えると何でも受け付けるのは
確かに危険ですね。
オーバーロード等、別の対策を考えます。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-02-23 10:18
Jittaさん、main()は

引用:

Jittaさんの書き込み (2005-02-22 21:10) より:
コード:
main() {
	Hoge h = new Hoge();
	Test(h);
	h.A = 10;
	System.Diagnostics.Debug.WriteLine(h.A);
}




じゃなくて
コード:
main() {
	Hoge h = new Hoge();
	h.A = 10;
	Test(h);
	System.Diagnostics.Debug.WriteLine(h.A);
}


じゃないでしょうか。

スキルアップ/キャリアアップ(JOB@IT)