6

最近、実装したいくつかのカスタム ユーザー コントロールにインターフェイスを追加しました。インターフェイスはかなり基本的です。チェーンをサポートするメソッドが 1 つあります。

Public Interface IMyInterface(Of T As WebControl)
    Function DoSomething() As T
End Interface

実装も非常に基本的です。

Public Class MyCustomControl
    Inherits CompositeControl
    Implements IMyInterface(Of MyCustomControl)

Public Function DoSomething() As MyCustomControl _
    Implements IMyInterface(Of MyCustomControl).DoSomething
    ' do stuff

    Return Me
End Class

この時点まではすべて正常に動作します。IMyInterface次のように、すべてがインターフェイスを実装するコントロールのコレクションをループしようとすると、問題が発生します。

Dim myList = New List(Of IMyInterface(Of WebControl))

myList.Add(someCustomControl)

myList.ForEach(Sub(i) i.DoSomething())

someCustomControlの代わりにMyCustomControl実装する です。IMyInterface(Of MyCustomControl)IMyInterface(Of WebControl)

2 行目 (追加しようとしている場所someCustomControl)でこのエラーが発生しています。

Option Strict On は、'MyCustomControl' から 'IMyInterface(Of WebControl)' への暗黙的な変換を禁止します。

このエラーを回避する方法はありますか? 私はそれを機能させることに近づいていますが、ジェネリックについて十分に知っているわけではありません。

4

3 に答える 3

4

共分散は、VS 2010 で導入された言語機能であり、問​​題を解決します。Tタイプの前にOutキーワードがあるように、ジェネリックを定義する必要があります。

Public Interface IMyInterface( Out T As WebControl)
    関数 DoSomething() As T
終了インターフェイス

Outキーワードを使用すると、共分散が使用されます。基本型のジェネリックの代わりに、より派生した型のジェネリックを使用できます。したがって、あなたの場合、ループなどIMyInterface(Of MyCustomControl))、コードが通常期待する場所でオブジェクトを許可します。IMyInterface(Of WebControl))for

共分散には制限があることに注意してください。共変型Tは関数の戻り値としてのみ使用でき、関数 (またはサブルーチン) へのパラメーターとしては使用できません。たとえば、DoSomething署名が次のようにIMyInterface見える場合、コンパイラは文句を言います。

' Here the type T is used as an input param - compiler error
Sub DoSomething(ByVal sampleArg As T)

あなたの連鎖シナリオを考えると、上記の制限は問題ではないと思います。

MSDN の詳細情報:

于 2013-06-14T03:28:04.783 に答える
0

オブジェクトを追加する前に、オブジェクトをキャストする必要があります。

myList.Add(CType(someCustomControl, IMyInterface(Of WebControl)))

また、インターフェイスをジェネリックではなく、「DoWork」メソッドの戻り値の型をインターフェイス自体にすることを検討することもできます。

Public Interface IMyInterface
    Function DoSomething() As IMyInterface
End Interface

インターフェース定義でタイプを指定する必要がある場合、インターフェースの能力が失われます (実装について知る必要はありません)。

于 2013-06-10T19:27:09.587 に答える