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'”

有什么办法可以做到这一点?

我已阅读并尝试过Suggestion 1Suggestion 2,但对于案例 1,我不能使用类型 T 作为表达式,在案例 2 中,我不能使用“类型”,因为这会在代码中出错(“类型不是定义”一)。

4

2 回答 2

3

AFAIK,您不能动态地执行此操作(可能没有反射和发射),因为编译器必须知道要为其生成代码的类型。

我通常使用由 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

这让我从数据库中得到正确的问题,反序列化该二进制文件并将它们转换为适当的问题类型。在其他情况下以及需要这种类型的铸造时非常可重用。

于 2013-03-08T10:57:39.980 回答