3

次のシナリオを考えてみましょう。

Public Interface IMyClass
End Interface

Public mustinherit class MyBaseClass : implements IMyClass
End Class

public class MyClass : inherits MyBaseClass
End Class

public class MyModel(of t as IMyClass)

    private Dim _parameter as t

    Public Sub New(byval parameter As t)
        _parameter As t
    End Sub
End class

私のコントローラーでは、これを問題なく実行できます。

Dim _myclass as IMyClass = new MyClass()

これと同様のことができますか:

Dim _myModel as MyModel(of IMyClass) = new MyModel(of MyClass)

???

変換が自動的に行われると思っていたので、最初の考えは間違っていましたが、行われていないようです。.NET 内で同じことを達成する方法はありますか?

編集 MyModel クラスを更新して、私が行っていたことをより多く示しました。作成したインスタンスを制約したいのですが、従来の非ジェネリック コードで縮小変換を行います。基本的に、私の部分的な Razor ビューには明示的なモデルが必要であり、それらのビューは、そのモデルを取得して表示する別のビューをレンダリングすることになります。モデルはすべて IMyClass を実装するクラスを実装または継承するため、すべてのメソッドがすべてのインスタンスに存在し、呼び出し可能である必要がありますが、型は交換できません。

4

2 に答える 2

1

少し変更しましょうMyModelか。

Public Class MyModel(Of T As IMyClass)
    Private _parameter As T

    Public Sub Something(parameter As T)
        _parameter = parameter
    End Sub
End class

Public Class MyClassA : Inherits MyBaseClass
End Class

Public Class MyClassB : Inherits MyBaseClass
End Class

Dim _myModel As MyModel(Of IMyClass) = New MyModel(Of MyClassA)()
_myModel.Something(New MyClassB()) ' Boom!

割り当てが許可されている場合、最後の行で問題が発生します。MyMode(Of MyClassA)._parameterタイプはMyClassAありますが、最後の行では (関連のない) type のオブジェクトが割り当てられますMyClassB。これは違法であるため、VB では禁止されています。

于 2013-03-08T16:00:00.793 に答える
0

複数の種類の MyModel が必要ですか、それとも格納されたオブジェクトを IMyClass に制限する必要があるだけですか?

最も簡単なアプローチ(必要なすべてを実行できない場合があります):

Public Interface IMyClass
    Sub DoIt()
End Interface

Public Class MyModel
    Private ReadOnly _parameter As IMyClass
    Public Sub New(parameter As IMyClass)
        _parameter = parameter
    End Sub
    Public Sub DoItToIt()
        _parameter.DoIt()
    End Sub
End Class

Public Class MyClassA
    Implements IMyClass
    Public Sub DoIt() Implements IMyClass.DoIt
    End Sub
End Class

Public Class Tests
    Public Sub Main()
        Dim model1 As MyModel = New MyModel(New MyClassA)
        model1.DoItToIt()
    End Sub
End Class

IHasMyClass複雑さの次のステップは、IMyClass を含むクラスのインターフェイスを定義することです。これは、含まれるオブジェクトの許可された型と実際の型に基づいた操作をサポートします。

Public Interface IMyClass
    Sub DoIt()
End Interface

Public Interface IHasMyClass
    Function GetIt() As IMyClass
    Function GetItsType() As Type
    Function GetAllowedType() As Type
End Interface

Public Class MyModel(Of T As IMyClass)
    Implements IHasMyClass

    Private ReadOnly _parameter As IMyClass
    Public Sub New(parameter As IMyClass)
        _parameter = parameter
    End Sub
    Public Sub DoItToIt()
        _parameter.DoIt()
    End Sub

    Public Function GetItAsT() As T
        Return _parameter
    End Function

    Public Function GetIt() As IMyClass Implements IHasMyClass.GetIt
        Return _parameter
    End Function

    Public Function GetItsType() As Type Implements IHasMyClass.GetItsType
        Return _parameter.GetType()
    End Function

    Public Function GetAllowedType() As Type Implements IHasMyClass.GetAllowedType
        Return GetType(T)
    End Function
End Class

Public Class MyClassA
    Implements IMyClass
    Public Sub DoIt() Implements IMyClass.DoIt
    End Sub
End Class

Public Class Tests
    Public Sub Main()
        ' Allow any IMyClass
        Dim model1 As MyModel(Of IMyClass) = New MyModel(Of IMyClass)(New MyClassA)
        model1.DoItToIt()
        Dim it As IMyClass = model1.GetIt()
        Dim allowedT As Type = model1.GetAllowedType()

        ' Restrict to MyClassA
        Dim modelA As MyModel(Of MyClassA) = New MyModel(Of MyClassA)(New MyClassA)
        modelA.DoItToIt()
        Dim itA1 As IMyClass = modelA.GetIt()
        Dim itA2 As MyClassA = modelA.GetItAsT()
        Dim allowedTA As Type = modelA.GetAllowedType()
    End Sub
End Class

Tests() では、 ANY IMyClass を受け入れる MyModel を作成するのかMyModel(Of IMyClass)、特定のサブクラスを必要とするMyModel を作成するのかを宣言する必要があることに注意してMyModel(Of MyClassA)ください。

上記のタイプのいずれかである MyModels を操作したい場合は、共通のインターフェースを使用します。

Dim model As IHasMyClass
model = model1
...
model = modelA

または、あなたの場合、MyModel のすべての機能をサポートするには、名前を に変更IHasMyClassIMyModel、さまざまな MyModel 関数を追加しますが、代わりにTを使用しますIMyClass

Public Interface IMyModel
    Function GetIt() As IMyClass
    Function GetItsType() As Type
    Function GetAllowedType() As Type

    Sub DoItToIt()
    Function CompareIt(other As IMyClass) As Integer
End Interface

そして、IMyClass と MyModel に適切な変更/追加を行います。

次に、次のことが可能になります。

Dim model As IMyModel = modelA
If model.CompareIt(model1.GetIt()) > 0 ...
于 2014-05-06T18:39:07.010 に答える