- PR -

C# パラメータの型が異なるメソッドを格納する方法

投稿者投稿内容
ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2007-05-07 15:30
パラメータの数や型が異なる一連のメソッドを逐次実行したい時に、メソッドと対をなすパラメータ情報を格納するうまい方法はありますか?

例えば、Graphicsオブジェクトへの描画メソッドが3個定義されているとします。
Graphics DrawLine(Pen,PointF,PointF)
Graphics DrawString(String,Font,Brush,PointF);
Graphics DrawImage(Image,PointF);

3個のメソッドを組み合わせて複雑な描画を実現する場合を想定します。
描画はGraphicsオブジェクトが取得可能になった時点で行いますが、
フォント、ペン、座標等必要なパラメータは描画する前に事前に確定するものとします。描画命令を実行するメソッドとこれと対をなすパラメータの情報を格納し、逐次実行する仕組みを考えていますが、良い方法が見つかりません。各メソッドのパラメータは数も型も異なるため、そのままではdelegateのコレクションに格納できません。
メソッドの種類は現在たったの3個ですが、増やす計画があります。
メソッドの追加を考慮しつつ煩雑さを避ける格納方法の知恵はありますか?

public void Test(Grahics g,Font font1,Brush brush1,Pen pen1,Image image1)
{
// 描画メソッドを逐次実行して複雑な描画を行う
// 下記のような一連の動作を格納したい
g.DrawString("abc",font1,brush1,new PointF(0,0));
g.DrawString("def",font1,brush1,new PointF(10,10));
g.DrawImage(image1,new PointF(10,20));
g.DrawLine(pen1,new PointF(15,15),new PointF(20,20));
.....
g.DrawString("ghi",font3,brush3,pointF5);
}

やはり、Reflectionを使うしか方法が無いのでしょうか?
分かりにくい説明ですみません。
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-05-07 15:41
「格納」というのが、つまりどういうことをしたいのか良く分かりません。

Test()というメソッドで、必要な処理(引数でフォントなどを指定して複雑な描画を行う)ができているのではないですか?
Test()のどこが不満なんでしょうか。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-05-07 15:58
行う仕事が違うならそれぞれ delegate を作るのがいいのではないでしょうか、

ただ、そのインターフェイスが頻繁に変わるというのなら、パラメータをクラスに押し込んであげれば引き渡す項目が変わったとしても、インターフェイス自体は変えなくても済みますよね。
_________________
かるあ のメモスニペット
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-05-07 16:00
引用:

やはり、Reflectionを使うしか方法が無いのでしょうか?



シグニチャの異なる既存のメソッドを統一的に呼び出そうと思ったら、
リフレクションしかないのではないでしょうか。

他には例えば、引数なしのDrawメソッドを持つインタフェースを定義して、
描画処理ごとの実装クラスを作成し、それらをコレクションに保持する
という案はあるかもしれませんが、良い方法かどうか何ともいえません。


わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2007-05-07 16:08
外してたら、ごめんなさい。

ファイルに保存したいということでしょうか?

次のようなイメージのファイルにしてはどうでしょうか?

コード:
DrawString,abc,FontA,Brush1,0,0
DrawImage,Filename.bmp,10,20
DrawLine,Pen1,15,15,20,20



で、次のようなコードで。( VB ですまん )

コード:
Select Case CSV(0)
	Case "DrawString"
		Dim str As String = CSV(1)
		Dim font1 As Font = FontDictionaly(CSV(2))
		Dim brush1 As Brush = BrushDictionaly(CSV(3))
		Dim p As Point = New Point( Integer.Parse( CSV(4)), Integer.Parse( CSV(5)) )
		g.DrawString( str, font1, brush1, p )
	
	Case "その他のいろいろ"
End Select


じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-05-07 16:42
引用:

よねKENさんの書き込み (2007-05-07 16:00) より:

他には例えば、引数なしのDrawメソッドを持つインタフェースを定義して、
描画処理ごとの実装クラスを作成し、それらをコレクションに保持する
という案はあるかもしれませんが、良い方法かどうか何ともいえません。


私はポリモーフィズムの出番となるべき場面だと読み取ったのですが、読み違えているのかな...
"メソッドを格納" というのはクラスのメンバとしたいと読み取りました。

# 件名を見た時はオーバーロードの話かと思ってしまいましたけど。(;^-^)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-05-07 18:18
私の中のエスパーがコマンドパターンと囁いてます。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-05-07 22:02
 一連の操作をしたい。その操作の中で、複数のメソッドを呼び出す。それぞれのメソッドで、必要な引数が違う。さて、どうしたものか?

じゃないの?

引用:

ひろしさんの書き込み (2007-05-07 15:30) より:
メソッドと対をなすパラメータ情報を格納するうまい方法はありますか?


これが、どういうことをしたいのか、よくわかりません。
例示されている Test メソッドで、何を delegate するのでしょう?DrawString などを delegate する?

 ここは、Test メソッドを別クラスに追い出し、必要なパラメータをインスタンスのプロパティなどで設定するんじゃないかなぁ?


 それとも、Test メソッドの中で呼び出す「一連の動作」を可変にしたいということでしょうか?それにしても「複雑な描画」をされるものをひとつのオブジェクトとしてとらえ、Draw メソッドひとつですませるのがいいんじゃないかなぁ?

_________________

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