VB.NET对泛型的约束

VB.NET对泛型的约束,.net,vb.net,generics,.net,Vb.net,Generics,我有一个这样声明的函数: Public Sub Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType) Public Class Products Inherits DAOBase 我还有一个名为Products的类,声明如下: Public Sub Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType) Public Class Products Inherits

我有一个这样声明的函数:

Public Sub Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType)
Public Class Products
Inherits DAOBase
我还有一个名为
Products
的类,声明如下:

Public Sub Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType)
Public Class Products
Inherits DAOBase
如你所见,如果我这样调用这个函数:

Modify(Of Products)(new Products())
这不是问题。当我试图将过去的对象转换为它的真实类型时,问题实际上出现了。例如:

CType(obj, Products)

两者都不起作用。我得到这个错误:

SIMTYPE类型的值无法转换为IMS.Products


我假设这是因为我使用泛型。有没有办法调整我的功能以允许像我尝试做的那样进行铸造操作?最后,我需要的是对对象的实际类型(本例中为产品)的引用。

您不能将
obj
强制转换为
Products
,因为没有任何约束可确保此转换有效,因此编译器假定它无效。无论如何,如果你的方法是泛型的,它不应该有特定类型参数的特定代码。如果当
SIMType
Products
时需要执行某些特定操作,请创建
Modify
方法的新重载。

可能是,您可以将Modify方法移动到DAOBase并使其可重写:

Public Class DAOBase
    Public Overridable Sub Modify()
        ' Work on DAOBase here
    End Sub
End Class

Public Class Products
    Inherits DAOBase

    Public Overrides Sub Modify()
        ' Work on Products here, without having to cast.
    End Sub
End Class
然后,可以为从DAOBase派生的所有类型调用Modify:

Dim obj As DAOBase = New Products()
obj.Modify()  ' Calls Products.Modify, even if obj is declared as DAOBase.
我建议使用-这是传统的面向对象编程,其中每个类中的方法根据它所在的类知道要做什么。无需浇铸;在所有情况下都会调用适当的
修改

但是,了解备选方案是很有用的,因此以下是一种完成问题中所问铸造的方法:

Public Sub Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType)
    Dim products1 As Products = TryCast(obj, Products)
    If products1 IsNot Nothing Then
        ... ' here you can use products1
    End If
End Sub

警告:当您发现自己在使用
TryCast
DirectCast
时,问问自己是否有不需要强制转换的替代解决方案。是的,这种替代方案可能需要对现有代码进行一些“重构”,但从长远来看,这种重构可能是值得的。

在许多情况下,泛型类型对某些特定类型进行特殊的大小写处理可能会有所帮助。除其他事项外,可以具有泛型类型
Woozle(of T)
,该泛型类型对其类型
T
的参数调用
Modify
,该参数可能或可能是存在特殊处理的类型。如果一个类型只适用于某些特定的选定类型,那么它可能是一个接口而不是一个类,但是一个泛型类可以适用于所有类型,但在某些特殊类型上效果特别好,这并没有什么问题。目前,当google“vb net泛型约束”出现时,这一点非常高,所以我想澄清发生了什么。首先,Olivier的回答表明,在这种特定情况下,泛型约束不是最好的方法——你根本不需要泛型,你只需要使用标准的面向对象编程,在基类中有一个在子类中重写的方法。第二,如果您确实希望(代码气味)代码与给定类型一起工作,请执行以下操作:
如果obj的类型是Products,则
将p作为Products=DirectCast(obj,Products)
。现在您可以使用
p
。但是,请尽量避免这种情况。顺便说一句,问题不是“因为您使用的是泛型”,而是因为您的参数类型不够具体,转换不够有效。如果普通(非泛型)函数的参数类型为
DAOBase
,则会出现类似错误。在这两种情况下,解决方案都涉及使用
DirectCast
TryCast