- PR -

参照渡し ref で、スーパークラスとして受け取るには

1
投稿者投稿内容
やまぐち03
会議室デビュー日: 2004/04/13
投稿数: 12
投稿日時: 2006-09-28 16:39
いつもお世話になっております。

VS2005 ASP.NET 2.0(C#.NET) で、 Webアプリケーションの開発をしています。

その中で、WebControlクラスを受け取り、処理を行うメソッドを作成しました。

private bool WebControlBind(WebControl ctrl)
{
if(ctrl is DropDownList)
{
...
}
else if(ctrl is RadioButtonList)
{
...
}
else if(ctrl is CheckBoxList)
{
...
}
...
}

private void Page_Load(object sender, System.EventArgs e)
{
// DropDownList ddl1 があるとします
WebControlBind(ddl1);

...
}


メソッドWebControlBindで受け取るパラメータctrlは、この記述では値渡しとなっていますが、サーバーメモリの節約を考え、参照渡しにしようと思い以下のように変更ました。

private bool WebControlBind(ref WebControl ctrl)
{
...(以下同じ)


実際にメソッドを使用する方にも ref を付ける必要が出てくると思いますが、
コンパイルエラーが出てしまい、うまくいきません

呼び出し側は
private void Page_Load(object sender, System.EventArgs e)
{
// DropDownList ddl1 があるとします
WebControlBind(ref ddl1);

...
}

コンパイルエラー内容:
引数 '1': 'ref System.Web.UI.WebControls.DropDownList' から 'ref System.Web.UI.WebControls.WebControl' に変換できません。

次のように直しても
private void Page_Load(object sender, System.EventArgs e)
{
// DropDownList ddl1 があるとします
WebControlBind(ref (WebControl)ddl1);

...
}


コンパイルエラー内容:
ref または out 引数は、割り当て可能な変数でなければなりません。





尚、以下のようにするとエラーが出なくなります
private void Page_Load(object sender, System.EventArgs e)
{
// DropDownList ddl1 があるとします
WebControl ctrl = (WebControl)ddl1;
WebControlBind(ref ctrl);

...
}


コンパイルエラーの回避方法又は、他にいい代替案等あればご教授賜りたく質問させていただきました。
宜しくお願いします。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-09-28 16:46
引用:

やまぐち03さんの書き込み (2006-09-28 16:39) より:
メソッドWebControlBindで受け取るパラメータctrlは、この記述では値渡しとなっていますが、サーバーメモリの節約を考え、参照渡しにしようと思い以下のように変更ました。


そんなに大差ない。
引用:

引数 '1': 'ref System.Web.UI.WebControls.DropDownList' から 'ref System.Web.UI.WebControls.WebControl' に変換できません。


そのままでref WebControl&型じゃないから。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2006-09-28 17:07
引用:

やまぐち03さんの書き込み (2006-09-28 16:39) より:
サーバーメモリの節約を考え、参照渡しにしようと思い以下のように変更ました。


ぶさいくろうさんは大差ないとおっしゃってますが、それでも言い足りないと思います。
小差もない位です。

引用:

やまぐち03さんの書き込み (2006-09-28 16:39) より:
尚、以下のようにするとエラーが出なくなります
private void Page_Load(object sender, System.EventArgs e)
{
// DropDownList ddl1 があるとします
WebControl ctrl = (WebControl)ddl1;
WebControlBind(ref ctrl);

...
}


参照型を参照渡しした場合にどのようにな処理が行われるかイメージできていますか。
この「エラーが出なくなる記述」をすると、参照渡しをした場合にお得になるメモリ領域と同じ位のメモリ領域を食い潰してしまっているというのは分かりますか?(参照型の変数をひとつ作っちゃってますもんね)

参照渡しというのは、参照を渡すんじゃなくて参照変数そのものを渡すような動作をします。だから、
ref または out 引数は、割り当て可能な変数でなければなりません。
って言われてるじゃないですか。
WebControlBind(ref new WebControl());
なんてこともできないでしょ。
(糞ったれVB.NETはできますけど)


結論としては「値渡ししましょう」です。

[ メッセージ編集済み 編集者: 一郎 編集日時 2006-09-28 17:14 ]
やまぐち03
会議室デビュー日: 2004/04/13
投稿数: 12
投稿日時: 2006-09-28 17:25
ぶさいくろう さん
一郎 さん

御返答ありがとうございました。

一郎さんのおっしゃる通り、参照渡しの参照渡しでは全く意味がないですね。
エラーを回避する事だけ考えてしまい、最初の目的を忘れていた感があります。

ここは素直に値渡しでいきます。
どうもありがとうございました!
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2006-09-28 17:37
引用:

やまぐち03さんの書き込み (2006-09-28 17:25) より:
一郎さんのおっしゃる通り、参照渡しの参照渡しでは全く意味がないですね。

ここは素直に値渡しでいきます。


参照渡しの参照渡しではなく、参照型の参照渡しですが、参照型を参照渡しする状況というのはほとんど無いと思います。私は思いつきません。
例えば「返り値にはboolで成功か失敗かを返して、さらにメソッドの中でnewしたオブジェクトの参照を返す」という場合には、refではなくoutを使うべきですし。
1

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