2016-12-11 4 views
1

多くの人が同じ問題を抱えていることがわかりましたが、修正方法が見つかりませんでした。List(Of OtherClass)を含むクラスを直列化するときのエラー

は、私は2クラスEmployeeDepartment

従業員を持っていると仮定し私は、次のコードを実行した

Imports System.ComponentModel 
Public Class Employee 
    Public Property Name As String 
    Public Property LastName As String 
    Public Property MotherName As String 

    Public Sub New(ByVal str1, ByVal str2, ByVal str3) 
     Name = str1 
     LastName = str2 
     MotherName = str3 
    End Sub 
End Class 

省クラス

Public Class Department 
    Public Property Employees As List(Of Employee) 

    Public Sub New() 
     Employees = New List(Of Employee) 
    End Sub 

    Public Sub WriteToXml(ByVal strXmlFilePath As String, 
          Optional ByVal encrypted As Boolean = False) 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     Dim sr As New StringWriter 
     Dim strObject As String = String.Empty 

     xs.Serialize(sr, Me) 

     If encrypted Then 
      Dim wrapper As Simple3Des = New Simple3Des("123") 
      strObject = wrapper.EncryptData(sr.ToString) 
     Else 
      strObject = sr.ToString 
     End If 

     Using sw As New StreamWriter(strXmlFilePath) 
      sw.Write(strObject) 
      sw.Close() 
     End Using 
    End Sub 

    Public Sub ReadFromXml(ByVal strXmlFilePath As String, 
          Optional ByVal encrypted As Boolean = False) 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     Dim strObject As String = String.Empty 
     Dim micResult As New Department 

     Using sr As New StreamReader(strXmlFilePath) 
      strObject = sr.ReadToEnd 

      If encrypted Then 
       Dim wrapper As Simple3Des = New Simple3Des("123") 
       strObject = wrapper.DecryptData(strObject) 
      End If 

      sr.Close() 
     End Using 

     micResult = DirectCast(xs.Deserialize(New StringReader(strObject)), Department) 
     Me.Employees.AddRange(micResult.Employees) 
     micResult.Dispose() 
    End Sub 

 Dim m As New Employee("A", "B", "C") 
     Dim m1 As New Employee("D", "E", "F") 
     Dim ml1 As New Department 
     Dim ml2 As New Department 

     ml1.Employees.Add(m) 
     ml1.Employees.Add(m1) 

     ml1.WriteToXml("1.xml") 

私は 'SerializerTest.Department'

問題はDepartmentクラスは私が見つけたList(of Employee)

が含まれていることである反射型エラーが発生しましたml1.WriteToXml("1.xml")

に例外が発生しました多くの記事はこの問題について話していますが、私はこれをどのように達成するのか今はありません。

Public Class Employee 

    Public Property Name As String 
    Public Property LastName As String 
    Public Property MotherName As String 

    Public Sub New() 

    End Sub 
    ... 

しかし、直列化メソッドは少し無駄です:

+1

XMLシリアル化のみを扱う場合は、 'Serializable'属性は必要ありません。バイナリシリアル化に使用されます。 –

+2

Employeeクラスはシンプルなものではないのでシリアライズできません。Departementをシリアル化する理由はありません - Deptの小道具(名前のようなもの)があれば、Employeeリストをシリアライズします。内側のオブジェクトを作成し、要素をMeにコピーします。それをDepartmentオブジェクトを返す共有メソッドにしてください...そして、CrytoStreamはその暗号メソッドよりも優れているかもしれません。 – Plutonix

+2

@VisualVincentデザイナーのシリアライズにも必要です。 – Plutonix

答えて

1

一番の問題はEmployeeは、パラメータなしのコンストラクタを持っていないということです。デシリアライズすると、Meに内部、一時オブジェクトからすべてのデータをコピーするのではなく、アプリで使用することにオブジェクトを作成して返すようにShared方法を行うことができます。

Public Class Department 
    ... 
    Public Shared Function Load(strXmlFilePath As String) As Department 
     Dim xs As New Serialization.XmlSerializer(GetType(Department)) 
     ' ToDo: return Nothing if file DNE 
     Using fs As New FileStream(strXmlFilePath, FileMode.Open) 
      Dim d As Department 
      d = xs.Deserialize(fs) 
      Return d 
     End Using 

    End Function 

は、次に作成/読み込み部門オブジェクト、そのメソッドを使用して:

Dim d As New Department 
d.Employees.Add(New Employee("ziggy", "jones", "")) 
d.Employees.Add(New Employee("zoey", "smith", "")) 
d.Employees.Add(New Employee("hoover", "greene", "q")) 

d.WriteToXml("C:\Temp\Depts.xml") 

Dim d2 = Department.Load("C:\Temp\Depts.xml") 
'd2.ReadFromXml("C:\Temp\Depts.xml") 

For Each emp In d2.Employees 
    Console.WriteLine(emp.Name) 
Next 

すべての私の従業員は、往復製:

ジギーを
zoey
hoover

関連する問題