Parameter.GetType() - 在编译时是否必须知道类型?

时间:2013-08-12 09:39:43

标签: vb.net oop generics object

这样的事情可能 - 如果是这样的话?

    Public Sub CreateGenericList(ByVal SampleObject As Object)
        Dim genericList as new List(Of SampleObject.GetType())
    End Function

我想创建一个能够反序列化给定XML文件的类。 XML文件包含自定义类型的序列化值,这在编译时是未知的。 我认为可能只使用参数SampleObject初始化类,然后为所有进一步的进展获取SampleObject的类型。 但似乎在编译时必须知道所有操作的类型? 有没有解决方法或者你可以向我解释这个问题吗?

上面的代码示例只是为了说明我的问题

感谢您的帮助, 贾尼斯

编辑:你的答案可能已经解决了问题,我会阅读更多关于“反思”和“泛型”的主题,如果我取得任何进展,让你保持最新。所以,谢谢你的帮助。

对于那些仍然感兴趣的人: 我被问到了我的问题的目的,并将尽力解释它。

    Public Function ReadAllObjects() As List(Of myObjectType)
        Dim result As New List(Of myObjectType)
        Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType)
        Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open)
        result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of myObjectType))
        FileReader.Close()
        RaiseEvent ReadingFinished()
        Return result
    End Function

这几乎总结了我想要创建的内容:一个EasyXmlHandling.dll供进一步使用,它将使用当前使用的变量类型进行初始化。 然后,通过调用“ReadAllObjects”(返回myObjectType的List)或“AddObject(ByVal theNewObject)”,它可以以非常简单的方式写入和读取XML文件...(更多功能)

我完全可以使用自定义类作为类型,所以我现在可以轻松地重新使用EasyXmlHandling代码,只需用我想要使用的任何新类替换源代码中的那个类型。 我更喜欢只用一个样本对象(或它的类型)来调用.dll,并让它自动完成其他所有操作。

我希望这是可以理解的,但我的英语和技术词汇都不是很好;)

再次感谢帮助和阅读。 我将尽力使用以前的所有答案,并在我取得进一步进展时更新主题。

1 个答案:

答案 0 :(得分:1)

不,这是不可能的(至少,没有使用反射)。在泛型列表或任何其他泛型类型中指定类型的重点是,编译器可以执行编译时类型检查。如果您没有在编译时指定类型,则根本没有任何好处。除了没有任何好处之外,它也不受支持。如果您在编译时不知道类型,则应该使用Object代替,因为这将适用于任何类型的对象,例如:

Dim myList As New List(Of Object)()

但是,如果你需要一个列表,它只允许一种类型的项目,但该类型在编译时是未知的,那么可以这样做,但你可能需要为某些东西创建自己的非通用列表类像那样。据我所知,框架中没有提供非泛型列表类,它将其项目限制为单个指定类型。

<强>更新

现在您已经解释了这样做的原因,很明显,仿制药是您的解决方案。例如,您可以将其实现为通用函数,如下所示:

Public Function ReadAllObjects(Of T)() As List(Of T)
    Dim result As New List(Of T)
    Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType)
    Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open)
    result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of T))
    FileReader.Close()
    RaiseEvent ReadingFinished()
    Return result
End Function

然后,你可以像这样调用它,传递你想要的类型:

Dim cars As New List(Of Car) = ReadAllObjects(Of Car)()
Dim boats As New List(Of Boat) = ReadAllObjects(Of Boat)()

正如您所看到的,这就是泛型的全部目的。它们是一个非常强大的工具,当你保持你的代码类型特定,但仍然能够重用不同类型。另一方面,反思并不适合这种特殊情况。反思也非常有用,但应始终被视为最后的选择。如果有另一种方法可以做到,没有反思,这通常是更好的方式。