2013-03-04 79 views
4

我有一個關於泛型類的序列化的問題。序列化一個通用類(不需要XML幫助器類)

因爲我想用一個通用類爲我所有的配置(它獲取序列化爲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,我已經使用了Google,發現了很多與該錯誤有關的文章。我在這裏沒有這樣做。我在泛型類上使用它。

難道還有比這樣的傢伙在這裏創建一個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 
+0

請張貼類的代碼你想序列化 – 2013-03-04 12:28:02

回答

1

是的,你使用派生類:ToolConfig。通過XmlInclude使其成爲已知,並且您應該沒問題:

<XmlInclude(GetType(ToolConfig))>添加到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) 
+0

ToolConfig只是一個例子。這應該是一個通用類。如果我指定類型「ToolConfig」,它不再是通用的。 在我將這裏的配置類修改爲通用之前,WriteToFile中的類型名稱是硬編碼的。因爲我現在在我的地方使用它,所以我希望它是通用的。 – 2013-03-04 12:29:51

+0

@wolfixx:我不明白你的意見,但你似乎也不明白這個問題。 'GenericConfig.WriteToFile'將'Me'傳遞給'Serialize'方法。現在,如果你有一個'ToolConfig'的實例並且調用'WriteToFile',你試圖序列化一個'ToolConfig'類型的對象 - 這是一個未知的派生類型。 – 2013-03-04 12:31:38

+0

我已經嘗試過了。我把' _'放在ToolConfig類定義的前面,但它沒有幫助。
不幸的是,我無法將它添加到GenericConfig類中。如果我這樣做,我會得到一個編譯錯誤,說XMLInclude不允許泛型參數。 – 2013-03-04 12:41:51