逐步解說:保存物件 (C# 和 Visual Basic)

雖然您可以在設計階段將物件屬性設定為預設值,但是當物件被毀棄時在執行階段輸入的任何值都會遺失。 您可以使用序列化,在執行個體間保存物件的資料,可讓您儲存值並在下次執行個體化該物件時將其擷取。

注意事項注意事項

在 Visual Basic 中,若要儲存簡單資料 (例如名稱或數字),您可以使用 My.Settings 物件。 如需詳細資訊,請參閱 My.Settings 物件 (Visual Basic)

在本逐步解說中,您將建立簡單的 Loan 物件,並將其資料保存至檔案。 接著在重新建立物件時,您將從檔案中擷取資料。 最後,您將修改程式碼,以 SOAP 格式保存物件。

安全性注意事項安全性注意事項

如果檔案不存在,這個範例就會建立新檔案。 如果應用程式必須建立檔案,此應用程式就必須擁有資料夾的 Create 使用權限。 所有的使用權限都是使用存取控制清單來設定。 如果檔案已存在,應用程式只需要 Write 使用權限,也就是較低的使用權限。 如果可以,更安全的做法是在部署期間建立檔案,並且只授與單一檔案的 Read 使用權限 (而不要授與資料夾的 Create 使用權限)。 此外,較安全的做法是將資料寫入使用者資料夾,而不要寫入根資料夾或 [Program Files] 資料夾。

安全性注意事項安全性注意事項

這個範例以二進位或 SOAP 格式檔儲存資料。 這些格式不適用於機密資料,例如密碼或信用卡資訊。

注意事項注意事項

根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。 如果要變更設定,請按一下 [工具] 功能表上的 [匯入和匯出設定]。 如需詳細資訊,請參閱 Visual Studio 設定

建立 Loan 物件

第一步是要建立 Loan 類別和使用該類別的測試應用程式。

若要建立 Loan 類別

  1. 建立新的類別庫專案並命名為 "LoanClass"。 如需詳細資訊,請參閱 HOW TO:建立方案和專案

  2. 在 [方案總管] 中,以滑鼠右鍵按一下 Class1 檔,然後按一下 [重新命名]。 將檔案重新命名為 Loan,並按下 ENTER。 重新命名檔案時也會將類別重新命名為 Loan。

  3. 加入下列 Public 成員至類別中:

    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 Form 應用程式專案加入至方案,請在 [檔案] 功能表上指向 [新增],然後按一下 [新增專案]。

  2. 在 [加入新的專案] 對話方塊中,輸入 LoanApp 做為專案名稱,再按一下 [確定] 關閉對話方塊。

  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.IOSystem.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 應用程式。 對於 Web 應用程式或 Web 服務,您可能會希望將物件保存至使用 SOAP 格式的 XML 檔案,使物件易於共用。

為了要將物件保存成 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 檔案。 若要檢視檔案,請選取 [方案總管] 中的 [顯示所有檔案] 選項,它位於 Windows 應用程式專案的 [Bin] 節點中。

注意事項注意事項

如果您已經在 [顯示所有檔案] 模式下,必須按一下 [檢視] 功能表中的 [重新整理] 重新整理檢視,才能看見檔案。

請注意,LoanClass 的三個成員以 XML 格式顯示。 請變更並儲存 XML 檔案中的 InterestRate 值,然後再次執行應用程式。 新利率將隨即出現在第二個文字方塊中。

請參閱

概念

C# 程式設計手冊

其他資源

序列化 (C# 和 Visual Basic)

Visual Basic 程式設計手冊