- PR -

配列のキャストについて

1
投稿者投稿内容
さな
ベテラン
会議室デビュー日: 2004/07/27
投稿数: 59
お住まい・勤務地: 大阪・肥後橋
投稿日時: 2005-09-29 13:16
いつもお世話になっております。
インターフェースAを継承する構造体Bの配列をA配列にキャストして、A配列を引数に持つメソッドの呼び出しを行う処理を考えています。
B[]をA[]にキャストしたいのですが、コンパイルエラーとなります。
メソッド内では、引数の値を変更しています。

以下の実現したいコードを簡略化して添付します。
コード:
public interface A
{
	int a
	{
		get;
		set;
	}
}
public struct B : A
{
	private int work;
	public int a
	{
		get{ return work; }
		set{ work = value; }
	}
}
public struct C : A
{
	private int work1;
	public int a
	{
		get{ return work1; }
		set{ work1 = value; }
	}
}

public class TestClass
{
	public TestClass(){}
	public void Method1(ref B[] Value)
	{
		A[] work = (A[])Value;	//コンパイルエラーとなる行
		Method3(ref work);
	}
	public void Method2(ref C[] Value)
	{
		A[] work = (A[])Value;	//コンパイルエラーとなる行
		Method3(ref work);
	}
	private void Method3(ref A[] Value)
	{
		Value[0].a = 10;
	}
}


どのようにすれば、配列のキャストが出来るのでしょうか?
ご教授よろしくお願いします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-09-29 13:24
こんにちは、じゃんぬ です。

引用:

さなさんの書き込み (2005-09-29 13:16) より:

どのようにすれば、配列のキャストが出来るのでしょうか?
ご教授よろしくお願いします。


配列を丸ごとキャストするのではなく、要素をひとつずつキャストして、
新しいインスタンスに追加していくことになります。
.NET Framework 的には CopyTo メソッドだとか、そういったメソッドを用意すると楽ですね。

# s/ご教授/ご教示


_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2005-09-29 13:39
ちなみにCLRでは
参照型の要素(class)を持つ配列はキャストすることができますが
値型の要素(struct)を持つ配列はキャストすることができません。
今回の場合はstructなのでキャストできないわけです。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-29 13:53
こんにちは。

コード:

// A[] work = (A[])Value; //コンパイルエラーとなる行
ArrayList list = new ArrayList(Value);
A[] work = (A[])list.ToArray(typeof(A));



こんなのどうですか?(じゃんぬねっとさんの方法の方が良いかな?)
また、上記のようにやっても、新しい配列ができているので、提示したメソッドにそのままコピーしても意図した通りにはならないでしょう。

#編集
ちなみに、今回のように、引数の配列の値を変えたい?という意図では、メソッドに ref はいりません。


[ メッセージ編集済み 編集者: 囚人 編集日時 2005-09-29 13:56 ]

[ メッセージ編集済み 編集者: 囚人 編集日時 2005-09-29 13:57 ]
さな
ベテラン
会議室デビュー日: 2004/07/27
投稿数: 59
お住まい・勤務地: 大阪・肥後橋
投稿日時: 2005-09-29 13:54
じゃんぬねっとさん、burton999さん、囚人さん、レス有難う御座います。
確かに、先ほど調べた本には
引用:

burton999さんの書き込み (2005-09-29 13:39) より:
ちなみにCLRでは
参照型の要素(class)を持つ配列はキャストすることができますが
値型の要素(struct)を持つ配列はキャストすることができません。
今回の場合はstructなのでキャストできないわけです。


このことが書かれていました。構造体(struct)が値型で有ることをすっかり忘れておりました。

皆さんの意見から二つの方法で回避できましたが、どちらが最適だとお考えでしょうか?
@Method1の処理を以下に変更
コード:

public void Method1(ref B[] Value)
{
A[] work = new A[Value.GetLength(0)];
Value.CopyTo(work,0);
Method2(ref work);
work.CopyTo(Value,0);
}



A構造体Bをクラスに変更する。

引用:

じゃんぬねっとさんの書き込み (2005-09-29 13:24) より:
# s/ご教授/ご教示


お恥ずかしい…

[ メッセージ編集済み 編集者: さな 編集日時 2005-09-29 13:55 ]

[ メッセージ編集済み 編集者: さな 編集日時 2005-09-29 13:56 ]

[ メッセージ編集済み 編集者: さな 編集日時 2005-09-29 13:58 ]
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2005-09-29 14:08
引用:

A構造体Bをクラスに変更する。



これは、なぜclassではなくstructで設計したのかに依存するので、なんとも言えません。
値型の使用法のガイドライン
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpgenref/html/cpconvaluetypeusageguidelines.asp
1

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