Пошаговое руководство. Сохранение объекта (C# и Visual Basic)

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

Примечание

В Visual Basic для хранения простых данных, таких как имя или число, можно использовать объект My.Settings.Дополнительные сведения см. в разделе Объект My.Settings (Visual Basic).

В данном пошаговом руководстве будет создан простой объект Loan и его данные будут сохранены в файле. В последствии можно воссоздать данные из файла при повторном создании объекта. Наконец, этот код можно изменить для хранения данных в формате SOAP.

Примечание о безопасностиПримечание по безопасности

Если такого файла не существует, этот пример создает новый файл.Если приложение должно создать файл, то ему необходимо разрешение на Create для папки.Для задания разрешений используются списки управления доступом.Если файл уже существует, приложению требуется лишь разрешение Write на запись.Возможно, безопаснее создать файл во время развертывания и предоставить разрешение Read для отдельного файла (вместо создания разрешений для папки).По тем же соображениям рекомендуется сохранять данные в пользовательских каталогах, а не в корневом каталоге или каталоге Program Files.

Примечание о безопасностиПримечание по безопасности

В этом примере данные сохраняются в файле в двоичном или SOAP формате.Эти форматы не следует использовать для конфиденциальных данных, таких как пароли или сведения о кредитных карточках.

Примечание

Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих настроек или выпуска.Чтобы изменить параметры, в меню Сервис выберите пункт Параметры импорта и экспорта.Дополнительные сведения см. в разделе Параметры Visual Studio.

Создание объекта Loan

Первым шагом является создание класса Loan и тестового приложения, которое использует этот класс.

Чтобы создать класс Loan

  1. Создайте новый проект библиотеки классов и назовите его LoanClass. Дополнительные сведения см. в разделе Практическое руководство. Создание решений и проектов.

  2. В обозревателе решений щелкните правой кнопкой мыши файл Class1 и выберите команду Переименовать. Переименуйте файл в Loan и нажмите клавишу ВВОД. При переименовании файла класс также будет переименован в Loan.

  3. Добавьте в класс следующие открытые члены:

    Public Class Loan
        Implements System.ComponentModel.INotifyPropertyChanged
    
        Public Property LoanAmount As Double
        Public Property InterestRate As Double
        Public Property Term As Integer
    
        Private p_Customer As String
        Public Property Customer As String
            Get
                Return p_Customer
            End Get
            Set(ByVal value As String)
                p_Customer = value
                RaiseEvent PropertyChanged(Me,
                  New System.ComponentModel.PropertyChangedEventArgs("Customer"))
            End Set
        End Property
    
        Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler _
          Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
        Public Sub New(ByVal loanAmount As Double,
                       ByVal interestRate As Double,
                       ByVal term As Integer,
                       ByVal customer As String)
    
            Me.LoanAmount = loanAmount
            Me.InterestRate = interestRate
            Me.Term = term
            p_Customer = customer
        End Sub
    End Class
    
    public class Loan : System.ComponentModel.INotifyPropertyChanged
    {
        public double LoanAmount {get; set;}
        public double InterestRate {get; set;}
        public int Term {get; set;}
    
        private string p_Customer;
        public string Customer
        {
            get { return p_Customer; }
            set 
            {
                p_Customer = value;
                PropertyChanged(this,
                  new System.ComponentModel.PropertyChangedEventArgs("Customer"));
            }
        }
    
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
        public Loan(double loanAmount,
                    double interestRate,
                    int term,
                    string customer)
        {
            this.LoanAmount = loanAmount;
            this.InterestRate = interestRate;
            this.Term = term;
            p_Customer = customer;
        }
    }
    

Необходимо также создать простое приложение, которое использует класс Loan.

Создание тестового приложения

  1. Чтобы добавить в решение проект приложения Windows Forms, в меню Файл выберите пункт Добавить, а затем щелкните Новый проект.

  2. В диалоговом окне Добавление нового проекта введите LoanApp в качестве имени проекта и щелкните кнопку OK, чтобы закрыть диалоговое окно.

  3. Выберите проект LoanApp в обозревателе решений.

  4. В меню Проект щелкните команду Назначить автозагружаемым проектом.

  5. В меню Проект щелкните команду Добавить ссылку.

  6. В диалоговом окне Добавление ссылки перейдите на вкладку Проекты и выберите проект LoanClass.

  7. Нажмите кнопку ОК, чтобы закрыть диалоговое окно.

  8. В конструкторе добавьте в форму четыре элемента управления TextBox.

  9. В редакторе кода добавьте следующий код:

    Private WithEvents TestLoan As New LoanClass.Loan(10000.0, 0.075, 36, "Neil Black")
    
    Private Sub Form1_Load() Handles MyBase.Load
        TextBox1.Text = TestLoan.LoanAmount.ToString
        TextBox2.Text = TestLoan.InterestRate.ToString
        TextBox3.Text = TestLoan.Term.ToString
        TextBox4.Text = TestLoan.Customer
    End Sub
    
    private LoanClass.Loan TestLoan = new LoanClass.Loan(10000.0, 0.075, 36, "Neil Black");
    
    private void Form1_Load(object sender, EventArgs e)
    {
        textBox1.Text = TestLoan.LoanAmount.ToString();
        textBox2.Text = TestLoan.InterestRate.ToString();
        textBox3.Text = TestLoan.Term.ToString();
        textBox4.Text = TestLoan.Customer;
    }
    
  10. Добавьте в форму обработчик события PropertyChanged, воспользовавшись следующим кодом:

    Public Sub CustomerPropertyChanged(
          ByVal sender As Object,
          ByVal e As System.ComponentModel.PropertyChangedEventArgs
        ) Handles TestLoan.PropertyChanged
    
        MsgBox(e.PropertyName & " has been changed.")
    End Sub
    
    private void CustomerPropertyChanged(object sender, 
        System.ComponentModel.PropertyChangedEventArgs e)
    {
        MessageBox.Show(e.PropertyName + " has been changed.");
    }
    

Теперь можно построить и запустить приложение. Обратите внимание на то, что в текстовых полях отображаются значения по умолчанию из класса Loan. Попробуйте изменить значение процентной ставки с 7,5 на 7,1, затем закройте приложение и запустите его снова — будет восстановлено заданное по умолчанию значение 7,5.

В реальной жизни процентная ставка время от времени меняется, но не при каждом запуске этого приложения. Чтобы не заставлять пользователя обновлять процентную ставку при каждом запуске приложения, рекомендуется сохранять самое последнее значение процентной ставки между экземплярами приложения. На следующем шаге для этого в класс Loan будет добавлена сериализация.

Использование сериализации для хранения объекта

Чтобы сохранить значения для класса Loan, прежде всего необходимо отметить класс атрибутом Serializable.

Чтобы отметить класс как сериализуемый

  • Измените объявление класса для класса Loan следующим образом:

    <Serializable()>
    Public Class Loan
    
    [Serializable()]
    public class Loan : System.ComponentModel.INotifyPropertyChanged
    {
    

Атрибут Serializable сообщает компилятору, что все находящееся в классе может быть сохранено в файле. Поскольку событие PropertyChanged обрабатывается в объекте Windows Form, его невозможно сериализовать. Атрибут NonSerialized используется для пометки членов класса, которые не следует сохранять.

Чтобы предотвратить сериализацию членов

  • Измените объявление события PropertyChanged следующим образом:

    <NonSerialized()>
    Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler _
      Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
    [field: NonSerialized()]
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    

Следующим шагом будет добавление кода сериализации в приложение LoanApp. Для сериализации класса и записи его в файл следует использовать пространства имен System.IO и System.Xml.Serialization. Во избежание ввода полных имен можно добавить ссылки на необходимые библиотеки классов.

Чтобы добавить ссылки на пространства имен

  • Добавьте в начало класса Form1 следующие инструкции:

    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
    
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    

    В данном случае используется двоичный форматер для сохранения объекта в двоичном формате. Далее в этом пошаговом руководстве код будет изменен для сохранения объекта в формате SOAP.

Следующим шагом является добавление кода десериализации объекта из файла при создании объекта.

Чтобы десериализовать объект

  1. Добавьте в класс константу для имени файла сериализованных данных.

    Const FileName As String = "..\..\SavedLoan.bin"
    
    const string FileName = @"..\..\SavedLoan.bin";
    
  2. Измените код процедуры события Form1_Load следующим образом:

    Private WithEvents TestLoan As New LoanClass.Loan(10000.0, 0.075, 36, "Neil Black")
    
    Private Sub Form1_Load() Handles MyBase.Load
        If File.Exists(FileName) Then
            Dim TestFileStream As Stream = File.OpenRead(FileName)
            Dim deserializer As New BinaryFormatter
            TestLoan = CType(deserializer.Deserialize(TestFileStream), LoanClass.Loan)
            TestFileStream.Close()
        End If
    
        AddHandler TestLoan.PropertyChanged, AddressOf Me.CustomerPropertyChanged
    
        TextBox1.Text = TestLoan.LoanAmount.ToString
        TextBox2.Text = TestLoan.InterestRate.ToString
        TextBox3.Text = TestLoan.Term.ToString
        TextBox4.Text = TestLoan.Customer
    End Sub
    
    private LoanClass.Loan TestLoan = new LoanClass.Loan(10000.0, 0.075, 36, "Neil Black");
    
    private void Form1_Load(object sender, EventArgs e)
    {
        if (File.Exists(FileName))
        {
            Stream TestFileStream = File.OpenRead(FileName);
            BinaryFormatter deserializer = new BinaryFormatter();
            TestLoan = (LoanClass.Loan)deserializer.Deserialize(TestFileStream);
            TestFileStream.Close();
        }
    
        TestLoan.PropertyChanged += this.CustomerPropertyChanged;
    
        textBox1.Text = TestLoan.LoanAmount.ToString();
        textBox2.Text = TestLoan.InterestRate.ToString();
        textBox3.Text = TestLoan.Term.ToString();
        textBox4.Text = TestLoan.Customer;
    }
    

    Прежде всего убедитесь, что файл существует. Если он существует, то создайте класс Stream для чтения двоичного файла и класс BinaryFormatter для преобразования файла. Кроме того, необходимо преобразовать тип потока в тип объекта Loan.

Далее необходимо добавить код для сохранения данных, введенных в текстовые поля класса Loan, и сериализовать класс в файл.

Чтобы сохранить данные и сериализовать класс

  • В процедуру события Form1_FormClosing добавьте следующий код:

    Private Sub Form1_FormClosing() Handles MyBase.FormClosing
        TestLoan.LoanAmount = CDbl(TextBox1.Text)
        TestLoan.InterestRate = CDbl(TextBox2.Text)
        TestLoan.Term = CInt(TextBox3.Text)
        TestLoan.Customer = TextBox4.Text
    
        Dim TestFileStream As Stream = File.Create(FileName)
        Dim serializer As New BinaryFormatter
        serializer.Serialize(TestFileStream, TestLoan)
        TestFileStream.Close()
    End Sub
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        TestLoan.LoanAmount = Convert.ToDouble(textBox1.Text);
        TestLoan.InterestRate = Convert.ToDouble(textBox2.Text);
        TestLoan.Term = Convert.ToInt32(textBox3.Text);
        TestLoan.Customer = textBox4.Text;
    
        Stream TestFileStream = File.Create(FileName);
        BinaryFormatter serializer = new BinaryFormatter();
        serializer.Serialize(TestFileStream, TestLoan);
        TestFileStream.Close();
    }
    

Теперь можно снова построить и запустить приложение. Первоначально в текстовых полях отображаются значения по умолчанию. Попробуйте изменить их и ввести имя в четвертое текстовое поле. Закройте приложение, а затем снова запустите его. Обратите внимание, что в текстовых полях отображаются новые значения.

Сохранение объекта с использованием формата SOAP

В предыдущем примере разобран порядок сохранения объекта в текстовом файле с использованием двоичного формата. Двоичный формат подходит для большинства приложений Windows. Для веб-приложений или веб-служб может потребоваться сохранение объекта в XML-файле с использованием формата SOAP, который облегчает совместное использование объекта.

Для сохранения объекта в формате SOAP сначала необходимо добавить ссылку на класс SoapFormatter. Класс SoapFormatter находится в собственном пространстве имен System.Runtime.Serialization.Formatters.Soap:

Для сохранения объекта в формате SOAP

  1. Выберите проект LoanApp в обозревателе решений.

  2. В меню Проект щелкните команду Добавить ссылку.

  3. В диалоговом окне Добавление ссылки щелкните по закладке .NET и выберите компонент System.Runtime.Serialization.Formatters.Soap.

  4. Нажмите кнопку ОК, чтобы закрыть диалоговое окно.

  5. В Редакторе кода добавьте в начало модуля Form1 следующую инструкцию:

    Imports System.Runtime.Serialization.Formatters.Soap
    
    using System.Runtime.Serialization.Formatters.Soap;
    
  6. Измените имя файла с SavedLoan.bin на SavedLoan.xml.

  7. В процедуре события Form1_Load измените объявление переменной deserializer следующим образом:

    Dim deserializer As New SoapFormatter
    
    SoapFormatter deserializer = new SoapFormatter();
    
  8. В процедуре события Form1_FormClosing измените объявление переменной serializer следующим образом:

    Dim serializer As New SoapFormatter
    
    SoapFormatter serializer = new SoapFormatter();
    

Теперь приложение можно построить и проверить. При первом запуске приложения будет создан файл SavedLoan.xml. Чтобы просмотреть файл, выберите параметр Показать все файлы в обозревателе решений; он расположен в узле Bin для проекта приложения Windows.

Примечание

Если уже установлен режим Показать все файлы, необходимо обновить представление, щелкнув Обновить в меню Вид для отображения файла.

Обратите внимание на то, что три члена LoanClass отображаются в формате XML. Измените значение InterestRate в XML-файле, а затем сохраните его и запустите приложение снова. Во втором текстовом поле появится новое значение процентной ставки.

См. также

Основные понятия

Руководство по программированию на C#

Другие ресурсы

Сериализация (C# и Visual Basic)

Руководство по программированию на Visual Basic