2012-01-06 12 views
2

私はModifyという機能を持っています。VB.Netの多態性ジェネリックスを扱うとき

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

この機能は一般的であることがわかります。 DAOBaseのサブクラスであるオブジェクト、またはDAOBaseのサブクラスをパラメタとして受け取ります。

修正機能インサイドそうのような呼び出しがあります:

DAOToGP(obj) 

多型が出番です。という4つのサブクラスがあります。私はこれらのタイプのそれぞれについてDAOToGP()を書いています。だから、Modify()関数では、DAOToGP(obj)を呼び出すと、多態性が発生し、Modify()に渡すタイプに応じて、DAOToGP()の正しい実装を呼び出す必要があります。

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

あなたはSIMTypeの代わりDAOBaseとしてobjを指定する必要があります。そうしないと、あなたのジェネリック型パラメータは役に立たないだろう

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

を。


EDIT:

あなたDAOToGP機能が異なるシグネチャを持っていると明らかに基本クラスから派生されていません。次にためDAOBaseから継承異なるクラスを宣言

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 

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 

あなたはまた、抽象機能(MustOverride)として抽象クラス(MustInherit)とDAOToGPとしてDAOBAse宣言することができます:これを試してみてください私の例ではDAOProductの異なるパラメータの組み合わせです。

+0

SIMTyeは、機能のいくつかの異なる場所で使用されます。しかし、なぜオーバーロードの解決に失敗するのですか?使用する 'DAOToGP()'の正しいバージョンが見つからないのはなぜですか? – user489041

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... 

または代替がOption Strict Offを使用して、

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

を書くしかし、私はこのOption Strict Offので無効をお勧めしませんすることで、このsimilar question

に見られるように、あなたはarray of delegates indexed by System.Typeを使用することができますいくつかの非常に便利なコンパイラチェック。