ジェネリックメソッドの型の制約について

タグの編集
投稿者 ひとみ  (学生) 投稿日時 2008/10/13 12:59:56


お世話になります。
VB2005(.NET Framework2.0)についての質問です。

VB2005でジェネリックメソッドを作成する場合、以下のように書きますが
ここでの制約で例えば「数値のみ」といった縛りは可能でしょうか?

Private Function Hoge(Of Type As 制約)(ByVal fuga As Type) As Byte()
    '例えばこんな事したい場合 
    Return BitConverter.GetBytes(fuga)
End Function

制約をかけないと以下のエラーが出ます。
「これらの引数で呼び出される、アクセス可能な 'GetBytes' がないため、オーバーロードの解決に失敗しました」
投稿者 うたひこ  (社会人) 投稿日時 2008/10/14 02:18:23
こんにちは。

数値の型をダイレクトに指定するやり方は存じ上げませんが、
(of T as structure)のように構造体を指定することはできます。

しかしながら、数値を指定したところで、
「数値=getbytesの引数」ではないので(例えば、intptrも数値ですが、このメソッドのオーバーロードにはありません)、例えばオーバーロードを仲介するメソッドとしてこちらを定義さるおつもりであるならば、構想自体が難のあるものだと思います。
投稿者 よねKEN  (社会人) 投稿日時 2008/10/14 22:24:59
こんにちは。
うたひこさんの回答とかぶる部分は省いて、制約についての補足情報を掲載します。

「Visual Basic におけるジェネリック型」より引用。
http://msdn.microsoft.com/ja-jp/library/w256ka79.aspx

>・型引数は、1 つまたは複数のインターフェイスを実装する。
>
>・型引数は、クラスの型そのものであるか、最大 1 つのクラスを継承する。
>
>・型引数はパラメータなしのコンストラクタを公開し、そのコンストラクタからオブジェクトを作成するコードで使用できるようにする。
>
>・型引数は、常に参照型である。または、常に値型である。

と説明があります。つまり、型引数の制約に指定できるのは以下の制約かその組合せだけです。

(1) あるインターフェースを実装していること
(2) あるクラス自身かそのクラスを継承していること
(3) 引数無しのコンストラクタを持つこと
(4) 参照型であること、または、値型であること

数値のみという条件は、(1)~(4)及びその組合せで表現できませんので実現できません。
例のコードでは実際には数値のみという条件ではなく、BitConverter.GetBytesメソッドの
引数として妥当かどうかという条件になっており、BitConverter.GetBytesメソッドのオーバーロード
の引数に(1)~(4)の観点で共通したルールを見出すことはできませんので、
例のようなコードは実現できません。
投稿者 ひとみ  (学生) 投稿日時 2008/10/15 06:09:58
うたひこさん、よねKENさんご返答ありがとうございます。

やっぱり無理がありますか^^;
よく考えたら、そもそも私が例に挙げたような事が可能だとしたらBitConverter.GetBytesメソッドも
最初からそういう実装になっていてもおかしくないですしね。

ジェネリクスはまだ勉強し始めたばかりだったんですが、大変よく分かりました。
ありがとうございました。