我在使用泛型类型时遇到了一些困难。我们有一个反序列化方法,签名如下:
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 1和Suggestion 2,但对于案例1,我不能将类型T用作表达式,而在案例2中,我不能使用“Of type”,因为它会出错在代码中(“类型未定义”一个)。
答案 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中获取正确的问题,反序列化该二进制文件并将它们转换为适当的问题类型。在其他情况下非常可重复使用,并且需要这种类型的铸造。