如何将类型传递给泛型类型?

时间:2013-03-01 11:14:54

标签: vb.net generics types

我在使用泛型类型时遇到了一些困难。我们有一个反序列化方法,签名如下:

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中,我不能使用“Of type”,因为它会出错在代码中(“类型未定义”一个)。

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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中获取正确的问题,反序列化该二进制文件并将它们转换为适当的问题类型。在其他情况下非常可重复使用,并且需要这种类型的铸造。