2012-01-06 53 views
2

我有一個叫做Modify的函數。它是這樣挖掘的:處理泛型時在VB.Net中的多態性

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 

我在這裏的損失也有點。我不知道爲什麼它無法確定要調用哪個函數。有任何想法嗎?

回答

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)。

+0

SIMTye在函數中使用了幾個不同的地方。但爲什麼過載解析失敗?爲什麼不能找到正確版本的'DAOToGP()'來使用 – user489041 2012-01-06 16:41:43

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看到一些很有用的編譯器檢查。