3

ジェネリック型の使用に問題があります。署名が次のようになる逆シリアル化メソッドがあります。

Public Function Deserialize(Of T)(ByVal compressedData As Byte()) As T

データベースにいくつかのバイナリデータがあります(type1.Question、type2.Question、...などのいくつかのタイプがあります)。Select caseだから、私のループに入るのを防ぐために、私は次のようなことを試みました:

Dim questionType as Type = question.getType()
Deserialize(Of questionType)(question)

このタイプは認識されません:「タイプ'questionType'は定義されていません」

これを達成する方法はありますか?

提案1提案2を読んで試しましたが、ケース1の場合、タイプTを式として使用できず、ケース2の場合、コードでエラーが発生するため、「タイプの」を使用できません(「タイプは定義された」1つ)。

4

2 に答える 2

3

私の知る限り、コンパイラはコードを生成するタイプを知る必要があるため、(おそらくリフレクションとエミットなしで)動的に行うことはできません。

私は通常、値がハンドラー オブジェクトである Type によってキー付けされた辞書を使用します。Deserializer オブジェクトがなくても、代わりにジェネリック関数にデリゲートを格納できます。

このようなもの(ヒップからチェックする必要があります):

'register these just once
_deserializers.Add(GetType(QuestionStyleOne), AddressOf(Deserialize(QuestionStyleOne)())

'later invoke by type, no select case
Dim questionType as Type = question.getType()
_deserializers(questionType)(question)
于 2013-03-01T13:40:08.477 に答える
1

私はついにこの問題の解決策を考え出しました。tcarvinからの提案から始めて、私はいくつかのことを変えて、この解決策にたどり着きました。

共有辞書を使用して、別のヘルパークラスを作成しました。

Private Shared _QuestionStyles As New Dictionary(Of Type, Func(Of Byte(), QuestionBase)) From {
    {GetType(QuestionStyleOne), Function(questionBinary)
                                                Return Deserialize(Of QuestionStyleOne)(questionBinary)
                                            End Function},
    {GetType(QuestionStyleTwo), Function(questionBinary)
                                                Return Deserialize(Of QuestionStyleTwo)(questionBinary)
                                            End Function}
}

その同じクラスで、辞書に格納されている関数を修正するために取得しようとするメソッドを作成しました。

Public Shared Function DoDeserializeQuestion(ByVal questionType As Type, ByVal questionBinary As Byte())
    Dim deserializeQuestion As Func(Of Byte(), QuestionBase) = Nothing
    If (_QuestionStyles.TryGetValue(questionType, deserializeQuestion)) Then
        Return deserializeQuestion(questionBinary)
    Else
        Throw New ArgumentException("QuestionType not known")
    End If
End Function

今、私はこれを呼び出す必要がありました:

Using reader As IDataReader = GetQuestions(id)
    While (reader.Read) 
        collection.Add(QuestionTypeHelper.DoDeserializeQuestion(question.GetType, CType(reader.Item(DataFields.Question), Byte())))
    End While
End Using

これにより、DBから適切な質問が取得され、そのバイナリが逆シリアル化され、適切な質問タイプにキャストされます。他の場合やそのタイプの鋳造が必要な場合に非常に再利用可能です。

于 2013-03-08T10:57:39.980 に答える