【问题标题】:Serialize a generic class (without the need of a XML helper class)序列化一个泛型类(不需要 XML 帮助类)
【发布时间】:2013-02-18 12:59:34
【问题描述】:

我有一个关于泛型类的序列化的问题。

因为我想为我的所有配置使用一个通用类(它被序列化为 XML),所以我编写了以下类:

Imports System.Xml
Imports System.Xml.Serialization
Imports System.IO
Imports System.Reflection
Imports System.Reflection.Assembly

<Serializable()> _
Public Class GenericConfig(Of T)
    Public Sub WriteToFile(ByVal FileName As String)
        ConfigVersion = ProgrammVersion.ToString
        Dim XmlFile As FileStream = New FileStream(FileName, FileMode.Create)
        Dim serialize As XmlSerializer = New XmlSerializer(GetType(GenericConfig(Of T)), New Type() {GetType(GenericConfig(Of T))})
        serialize.Serialize(XmlFile, Me)
        XmlFile.Close()
    End Sub

    Public Shared Function ReadFromFile(ByVal FileName As String) As GenericConfig(Of T)
        Dim XmlFile As FileStream = New FileStream(FileName, FileMode.Open)
        Dim serialize As XmlSerializer = New XmlSerializer(GetType(GenericConfig(Of T)))
        ReadFromFile = serialize.Deserialize(XmlFile)
        XmlFile.Close()
        Return ReadFromFile
    End Function

    Public Shared ReadOnly Property ConfigFileName() As String
        Get
            Return GetExecutingAssembly.Location.Substring(0, GetExecutingAssembly.Location.Length - 4) & ".Config.xml"
        End Get
    End Property
End Class

Public Class ToolConfig
    Inherits GenericConfig(Of ToolConfig)

    Public Property Key1 As String = "Value 1"
End Class

我遇到的问题是我无法序列化它,因为行中出现以下错误

serialize.Serialize(XmlFile, Me)

{“GenericConfigClass.ToolConfig 类型不是预期的。使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。”}

如果您在派生类上使用 XMLSerializer,我已经搜索并发现了很多与该错误相关的文章。我在这里不这样做。我在泛型类上使用它。

除了在这里创建一个 XML 帮助器类之外,还有其他方法吗: http://www.codeproject.com/Articles/35925/Generic-XML-Serialization-Methods

谢谢,
沃尔夫冈

更新:
这就是我所说的(简短的例子)

Imports System.IO

Public Class frmMain
    Dim Config As ToolConfig

    Private Sub btnConfigInit_Click(sender As Object, e As EventArgs) Handles btnConfigInit.Click
        '----------------- read config file  -----------------
        If File.Exists(ToolConfig.ConfigFileName) Then
            Config = ToolConfig.ReadFromFile(ToolConfig.ConfigFileName)
        Else
            Config = New ToolConfig
        End If
        Config.WriteToFile(ToolConfig.ConfigFileName)

        MsgBox(Config.Key1)
    End Sub
End Class

【问题讨论】:

  • 请贴出您要序列化的类的代码

标签: vb.net visual-studio-2010 generics xml-serialization


【解决方案1】:

是的,您正在使用派生类:ToolConfig。通过XmlInclude 告知您应该没问题:

&lt;XmlInclude(GetType(ToolConfig))&gt; 添加到GenericConfig

另一种解决方案应该是在创建XmlSerializer 实例时简单地使用Me.GetType() 而不是GetType(GenericConfig(Of T))

Dim serialize As XmlSerializer = New XmlSerializer(Me.GetType())

为了能够成功反序列化,您必须将共享的ReadFromFile 方法设为实例方法或使其成为通用方法。


如果您想保持该反序列化方法共享,您可以这样做:

Public Class GenericConfig ' <- No (Of T) here! But in the line below.
    Public Shared Function ReadFromFile(Of T)(ByVal FileName As String) As T
        Dim XmlFile As FileStream = New FileStream(FileName, FileMode.Open)
        Dim serialize As XmlSerializer = New XmlSerializer(GetType(T))
        ReadFromFile = serialize.Deserialize(XmlFile)
        XmlFile.Close()
        Return ReadFromFile
    End Function
End Class

用法:

GenericConfig.ReadFromFile(Of ToolConfig)(filename)

【讨论】:

  • ToolConfig 只是一个例子。这应该是一个通用类。如果我指定类型“ToolConfig”,它将不再是通用的。在我将我的配置类修改为通用之前,WriteToFile 中的类型名称是硬编码的。因为我现在在我的地方使用它,所以我希望它是通用的。
  • @wolfixx:我不明白你的评论,但你似乎也不明白这个问题。 GenericConfig.WriteToFileMe 传递给 Serialize 方法。现在,如果您有一个 ToolConfig 的实例并在其上调用 WriteToFile,则您正在尝试序列化 ToolConfig 类型的对象 - 这是一个未知的派生类型。
  • 我已经试过了。我将 ' _' 放在 ToolConfig 类定义的前面,但它没有帮助。
    不幸的是,我无法将它添加到 GenericConfig 类中。如果我这样做了,我会收到一个编译错误,指出 XMLInclude 不允许泛型参数。
  • @wolfixx:请查看更新。您需要将 ToolConfig 的 XmlInclude 添加到 GenericConfig。这不应该给出任何关于泛型参数的错误,因为 ToolConfig 没有任何错误。
  • 感谢 Daniel 的帮助。对此,我真的非常感激。我不想这样做的原因是 GenericConfig 不再是通用的。我想将 GenericConfig 放入不同的命名空间/dll 中,并将 if 用于以后的项目。今天是 ToolsConfig,明天可能是 PlaneConfig 或 WorldConfig(只是一些示例 :-) 我不想每次重用该代码时都重新编译基类。否则,我目前正在做的事情没有任何优势(我有一个非通用类版本,我将其复制到我所做的每个项目中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
  • 2010-12-15
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-02-18
  • 2020-12-18
相关资源
最近更新 更多