我有一个名为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
我在这里有点不知所措。我不知道为什么它无法确定要调用哪个函数。有什么想法吗?
答案 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
禁用了一些非常有用的编译器检查。