Иллюстрированный самоучитель по VB.NET

       

Практический пример: динамический список с поддержкой сериализации


Прежде чем приводить полный код примера, мы хотим предупредить об одной потенциальной трудности, которая постоянно возникает при восстановлении сохраненных объектов, а особенно объектов, хранящихся в динамических списках. Итак, после завершения восстановления мы получаем набор обобщенных объектов, хранящихся в динамическом массиве. Но как определить истинный тип этих объектов, чтобы выполнить правильное преобразование? В следующем примере эта информация жестко фиксируется в процессе восстановления, поскольку мы точно знаем порядок занесения объектов иерархии Employee в массив. В более общей ситуации эти сведения пришлось бы сохранять в отдельном файле.

В настоящем примере мы создаем менеджера (класс Manager) с именем Sally и секретаря (класс Secretary) с именем Тот. Класс Manager содержит внутренний объект класса Secretary в одной из переменных; класс Secretary содержит ссылку на Manager.

Не забудьте включить в решение ссылку на сборку System.Runtime.Serialization.For-matters.Soap, это необходимо для работы программы.

Ниже приведен код тестовой части программы. Три ключевые строки выделены жирным шрифтом:

Option Strict On

' Использует сборку System.Runtime.Serialization.Formatters.Soap

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters

Module Modulel

Sub Main()

Dim Sally As New Manager("Sally". 150000)

Dim Tom As Secretary



Tom = New Secretary("Tom". 100000, Sally)

Sally.MySecretary = Tom

Dim Employees As New ArrayList() Employees. Add(Tom)

Employees.Add(Sally)

Console.WriteLine(Tom.TheName & "is employee " & _

Tom.ThelD & "and has salary " & Tom.Salary)

Console.WriteLine("Tom's boss is " & Tom.MyManager.TheName)

Console.WriteLine("Sally's secretary is " & Sally.MySecretary.TheName)

Console. WriteLine() Console.Writel_ine(Sally.TheName & "is employee " & _

Sally.ThelD & "has salary " & Sally.Salary) Sally.RaiseSalary(0.lD)


Console.WriteLinet"After raise " & Sally.TheName &_ "has salary "_

& Sally.Salary)



Рис.9.5. Сериализация динамического массива

Ниже приведена остальная часть кода этого примера.

Sub SerializeToSoap(ByVal myEmployees As ArrayList._

ByVal fName As String)

Dim fStream As FileStream

Dim mySoapFormatter As New Formatters.Soap.SoapFormatter()

Try

fStream = New FileStreamtfName. FileMode.Create.FileAccess.Write)

mySoapFormatter.Serialize(fStream. myEmployees)

Catch

Throw Finally

If Not (fStream Is Nothing) Then fStream.Close()

End Try

End Sub

Function DeSerializeFromSoap(ByVal fName As String) As ArrayList

Dim fStream As New FileStream(fName. Fi1eMode.Open. FileAccess.Read)

Dim mySoapFormatter As New Formatters.Soap.SoapFormatter()

Try

fStream = New FileStream(fName, FileMode.Open. FileAccess.Read)

Return

CType(mySoapFormatter.Deserialize(fStream), ArrayList)

Catch

Throw Finally

If Not (fStream Is Nothing) Then fStream.Close()

End Try

End Function

End Module

<Serializable()>Public Class Employee

Private m_Name As String

Private m_Salary As Decimal

Private Const LIMIT As Decimal = 0.1D

Private Shared m_EmployeeId As Integer = 1000

Private m_myID As Integer

Public Sub New(ByVal sName As String. ByVal curSalary As Decimal)

m_Name = sName

m_Salary = curSalary

m_myID = m_EmployeeId

m_EmployeeId = m_EmployeeId + 1

End Sub

Readonly Property TheIDO As Integer

Get

Return mjnyID

End Get

End Property Readonly Property TheName()As String

Get

Return m_Name

End Get

End Property Readonly Property Salary()As Decimal

Get

Return MyClass.m_Salary

End Get

End Property Public Overridable Overloads

Sub RaiseSalary(ByVal Percent As Decimal)

If Percent > LIMIT Then

' Недопустимая операция

Console.WriteLineC'MUST HAVE PASSWORD " & _

"TO RAISE SALARY MORE THAN LIMIT!!!!") Else

m_Salary = (1 + Percent) * m_Salary

End If

End Sub

Public Overridable Overloads



Sub RaiseSa1ary(ByVal Percent As Decimal._

ByVal Password As String) If Password = "special" Then

m_Salary = (1 + Percent) * m_Salary

End If

End Sub

End Class

<Serializable()>Public Class Manager

Inherits Employee

Private m_Sec As Secretary

Private m_Salary As Decimal

Public Sub New(ByVal sName As String,_

ByVal curSalary As Decimal)

MyBase.New(sName. curSalary)

End Sub

Public Sub New(ByVal sName As String.ByVal curSalary As Decimal.

ByVal mySec As Secretary)

MyBase.New(sName.curSalary)

m_Sec = mySec

End Sub

Property MySecretary()As Secretary Get

Return m_Sec End Get Set(ByVal Value As Secretary)

m_Sec = Value

End Set

End Property

Public Overloads Overrides

Sub RaiseSalary(ByVal percent As Decimal)

MyBase.RaiseSalary(2 * percent, "special")

End Sub

End Class

<Serializable()>

Public Class Secretary Inherits Employee

Private m_Boss As Manager

Public Sub New(ByVal sName As String. ByVal curSalary As Decimal,

ByVal myBoss As Manager) MyBase.New(sName, curSalary)

m_Boss = myBoss

End Sub

Property MyManager() As Manager Get

Return m_Boss

End Get Set(ByVal Value As Manager)

m_Boss = Value

End Set

End Property

End Class


Содержание раздела