2011-01-08 10 views
1

vb.netでは、複数の制約を満たす一般的なパラメータで操作できる関数を設計することができます。たとえば、Controlから継承し、IListを実装するクラスをパラメータとして受け入れることができます。この関数は、そのようなオブジェクトに対して "Control"または "IList"メソッドを使用し、オブジェクトをControlまたはIListを必要とするものに渡すこともできます(この特定の組み合わせは、有用な組み合わせ]。複数制約汎用関数呼び出しは実際にどのように機能しますか?

 
    Sub CrossThreadAdd(Of T, U As {Control, IList(Of T)})(ByVal TheControl As U, ByVal NewThing As T) 
     If TheControl.InvokeRequired Then 
      TheControl.BeginInvoke(New Action(Of U, T)(AddressOf CrossThreadAdd), TheControl, NewThing) 
     Else 
      TheControl.Add(NewThing) 
     End If 
    End Sub 

この方法は、コンパイル時の型安全性を提供します。実行時に失敗する可能性のあるキャストの必要はありません。代わりの方法として、引数をControlまたはIListのどちらかとして渡し、関数を他のものにキャストする方法があります。ただし、渡されたオブジェクトが両方の制約を実際に満たしていない場合は、実行時に失敗します。

上記のような汎用関数を使用すると良いでしょうか?どちらの制約を満たすオブジェクトにIListableControl(Of T)のような新しいインタフェースがあるのが良いのでしょうか?コントロールとしてキャストされるTheControlプロパティ、および汎用ISelf(T)インターフェイスを持つ方がよい場合は、それ自体が返される「自己」プロパティを提供することが期待される実装者Tとして?

複数の制約のあるジェネリックを使用すると、実行時の型キャストを必要とせずに多くのことを実行できますが、パフォーマンスのコストについてはわかりません。実行時に65,536種類のジェネリック型を生成するための短いプログラムを作成しようとしました。 Foo(Of Foo(Of Foo(Of Blah))...))))))、それはかなり遅くなったので、ジェネリックスを処理するのに必要な時間

答えて

1

の次にある必要があります。通常の機能よりも一般的な機能へのランタイムオーバーヘッド同様に、制約の数は実行時に全く影響しません。 コンパイラによって確認されています。当然の違うものは、あなたがこれらの機能にアクセスするためにリフレクションを使用しているときに適用されます。そのような制約が有用であなたの質問については

...

個人的には、私は言う:頻繁に。インターフェースは、の1つだけのモデルにする必要があります。集約インターフェース(例えば、IListableControl)を使用すると、コードの臭いのように聞こえるようになります(もちろん、複数の制約を持つジェネリックが存在することを前提としています。

+0

集約インターフェイスを使用せずに、オブジェクトインスタンスをフィールドまたはコレクションに格納して、後で複数制約の汎用関数に渡すことはできますか?また、*いくつかのオーバーヘッドが必要であると確信しています - ジェネリックスがクラス制約を持っていても、ジェネリック関数は渡された型がパラメータの型に依存しないことを知っています( "U" ListBox "、TheControlは" FancyRainbowColoredListbox "のインスタンスである可能性があります)。 – supercat

+0

@supercat:もちろん、必要な制約を持つクラス(例: 'Of T、U As {Control、Of T)})でコレクションをカプセル化し、その型を内部で使用するだけで済みますコレクション(例えば 'List(Of U)')。あなたはなぜオーバーヘッドがあると確信していますか?すべての型テストは厳密にコンパイル時にのみ行われます!型がコンパイル時に決定できない場合、コードはコンパイルされません。 –

+0

コレクション内のすべてのものが同じタイプで、コンパイル時にタイプが解決できる場合は、問題はありません。ただし、ControlとIList(Of T)の両方を継承する2つ以上のクラスがありますが、IList(Of T)を継承する共通祖先はありません。その中の項目を二重制約法に渡すことができるように、そのような集合を宣言する方法はありますか? – supercat

関連する問題