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)._parameterhas typeMyClassA但最后一行会分配一个(不相关的)类型的对象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 的 MyModelMyModel(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 回答