处理泛型时VB.Net中的多态性

时间:2012-01-06 16:28:06

标签: .net vb.net polymorphism

我有一个名为Modify的函数。它是这样的:

Public Function Modify(Of SIMType As {New, DAOBase})(ByVal obj As DAOBase) As Boolean

您可以看到此功能是通用的。作为一个参数,它是DAOBase或DAOBase的子类。

在修改功能中,有一个如下调用:

DAOToGP(obj)

这是多态性发挥作用的地方。我创建了DAOBase四个左右的子类。我已为每种类型写了DAOToGP()。所以在Modify()函数中,当它调用DAOToGP(obj)时,多态性应该启动,它应该调用DAOToGP()的正确实现,具体取决于我传入Modify()的类型

但是,我收到以下错误:

Error   20  Overload resolution failed because no accessible 'DAOToGP' can be called without a narrowing conversion:
'Public Shared Function DAOToGP(distributor As Distributors) As Microsoft.Dynamics.GP.Vendor': Argument matching parameter 'distributor' narrows from 'SierraLib.DAOBase' to 'IMS.Distributors'.
'Public Shared Function DAOToGP(product As Products) As Microsoft.Dynamics.GP.SalesItem': Argument matching parameter 'product' narrows from 'SierraLib.DAOBase' to 'IMS.Products'. C:\Users\dvargo.SIERRAWOWIRES\Documents\Visual Studio 2010\Projects\SIM\Dev_2\SIM\IMS\DVSIMLib\GP\GPSIMRunner\Runners\RunnerBase.vb 66  39  IMS

我在这里有点不知所措。我不知道为什么它无法确定要调用哪个函数。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您必须将obj指定为SIMType而不是DAOBase

Public Function Modify(Of SIMType As {New, DAOBase})(ByVal obj As SIMType) As Boolean

否则你的泛型类型参数将毫无用处。


编辑:

您的DAOToGP功能具有不同的签名,显然不是从基类派生的。试试这个:

Public Class DAOBase(Of Tin, Tout)
    Public Function DAOToGP(ByVal obj As Tin) As Tout
    End Function
End Class

Public Module Test_DAOBase
    Public Function Modify(Of Tin, Tout)(ByVal obj As DAOBase(Of Tin, Tout)) As Boolean
    End Function
End Module

您还可以将DAOBAse声明为抽象类(MustInherit),将DAOToGP声明为抽象函数(MustOverride):

Public MustInherit Class DAOBase(Of Tin As {New}, Tout)
    Public MustOverride Function DAOToGP(ByVal obj As Tin) As Tout
End Class

Public Class DAOProduct
    Inherits DAOBase(Of Products, SalesItem)

    Public Overrides Function DAOToGP(ByVal obj As Products) As SalesItem
        Return Nothing
    End Function
End Class

Public Module Test_DAOBase
    Public Function Modify(Of Tin As {New}, Tout)(ByVal obj As DAOBase(Of Tin, Tout)) As Boolean
        Dim out As Tout = obj.DAOToGP(New Tin())     'This is OK
    End Function

    Public Sub TestModify()
        Dim daoProd = New DAOProduct()
        Modify(daoProd)  'This is OK
    End Sub
End Module

然后为参数类型的不同组合声明继承自DAOBase的不同类(在我的示例中为DAOProduct)。

答案 1 :(得分:0)

您要做的是根据参数的运行时类型在运行时执行重载解析。但VB重载在编译时而不是运行时解决。 (除非您使用Option Strict Off,请参阅稍后的内容。)

顺便说一下,问题与泛型的使用无关 - 在非通用例程中它也是一样的。

针对如此少数类型的最佳解决方案可能是一个简单的If块。

If obj Is TypeOf subclassone Then
  Dim obj1 As subclassone
  obj1 = obj
  DAOToGP(obj1)
ElseIf obj Is TypeOf subclasstwo Then
  Dim obj2 As subclasstwo
  obj2 = obj
  DAOToGP(obj2)
  'and so on... 

或者您可以使用此array of delegates indexed by System.Type

中显示的similar question

另一种方法是使用Option Strict Off然后写

Dim objWhatever As Object
objWhatever = obj
DAOToGP(obj)  ' resolved at runtime, might Throw

但我不推荐这个因为Option Strict Off禁用了一些非常有用的编译器检查。