逐步解說:保存物件 (C# 和 Visual Basic)
雖然您可以在設計階段將物件屬性設定為預設值,但是當物件被毀棄時在執行階段輸入的任何值都會遺失。 您可以使用序列化,在執行個體間保存物件的資料,可讓您儲存值並在下次執行個體化該物件時將其擷取。
注意事項 |
---|
在 Visual Basic 中,若要儲存簡單資料 (例如名稱或數字),您可以使用 My.Settings 物件。如需詳細資訊,請參閱My.Settings 物件。 |
在本逐步解說中,您將建立簡單的 Loan 物件,並將其資料保存至檔案。 接著在重新建立物件時,您將從檔案中擷取資料。 最後,您將修改程式碼,以 SOAP 格式保存物件。
安全性提示 |
---|
如果檔案不存在,這個範例就會建立新檔案。如果應用程式必須建立檔案,此應用程式就必須擁有資料夾的 Create 使用權限。所有的使用權限都是使用存取控制清單來設定。如果檔案已存在,應用程式只需要 Write 使用權限,也就是較低的使用權限。如果可以,更安全的做法是在部署期間建立檔案,並且只授與單一檔案的 Read 使用權限 (而不要授與資料夾的 Create 使用權限)。此外,較安全的做法是將資料寫入使用者資料夾,而不要寫入根資料夾或 [Program Files] 資料夾。 |
安全性提示 |
---|
這個範例以二進位或 SOAP 格式檔儲存資料。這些格式不適用於機密資料,例如密碼或信用卡資訊。 |
注意事項 |
---|
根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。如果要變更設定,請按一下 [工具] 功能表上的 [匯入和匯出設定]。如需詳細資訊,請參閱Visual Studio 設定。 |
建立 Loan 物件
第一步是要建立 Loan 類別和使用該類別的測試應用程式。
若要建立 Loan 類別
建立新的類別庫專案並命名為 "LoanClass"。 如需詳細資訊,請參閱建立方案與專案。
在 [方案總管] 中,以滑鼠右鍵按一下 Class1 檔,然後按一下 [重新命名]。 將檔案重新命名為 Loan,並按下 ENTER。 重新命名檔案時也會將類別重新命名為 Loan。
加入下列 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 類別的簡單應用程式。
若要建立測試應用程式
若要將 Windows Form 應用程式專案加入至方案,請在 [檔案] 功能表上指向 [新增],然後按一下 [新增專案]。
在 [加入新的專案] 對話方塊中,輸入 LoanApp 做為專案名稱,再按一下 [確定] 關閉對話方塊。
在 [方案總管] 中選取 LoanApp 專案。
在 [專案] 功能表上,按一下 [設定為啟始專案]。
在 [專案] 功能表上,按一下 [加入參考]。
在 [加入參考] 對話方塊中,按一下 [專案] 索引標籤並選取 [LoanClass] 專案。
按一下 [確定] 以關閉對話方塊。
在設計工具中,將四個 TextBox 控制項加入至表單。
在程式碼編輯器中,加入下列程式碼:
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; }
使用下列程式碼,將 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 格式儲存物件。
接下來是要加入程式碼,在建立物件時從檔案還原序列化物件。
若要還原序列化物件
將常數加入至序列化資料的檔案名稱類別。
Const FileName As String = "..\..\SavedLoan.bin"
const string FileName = @"..\..\SavedLoan.bin";
修改 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 格式保存物件
在 [方案總管] 中選取 LoanApp 專案。
在 [專案] 功能表上,按一下 [加入參考]。
在 [加入參考] 對話方塊中,按一下 [.NET] 索引標籤,然後選取 System.Runtime.Serialization.Formatters.Soap 元件。
按一下 [確定] 以關閉對話方塊。
在 [程式碼編輯器] 中,將下列陳述式加入至 Form1 模組的最上方:
Imports System.Runtime.Serialization.Formatters.Soap
using System.Runtime.Serialization.Formatters.Soap;
將檔案名稱從 SavedLoan.bin 變更為 SavedLoan.xml。
在 Form1_Load 事件程序中,將 deserializer 變數的宣告變更如下:
Dim deserializer As New SoapFormatter
SoapFormatter deserializer = new SoapFormatter();
在 Form1_FormClosing 事件程序中,將 serializer 變數的宣告變更如下:
Dim serializer As New SoapFormatter
SoapFormatter serializer = new SoapFormatter();
此時,您可以建置並測試應用程式。 首次執行應用程式時,會建立 SavedLoan.xml 檔案。 若要檢視檔案,請選取 [方案總管] 中的 [顯示所有檔案] 選項,它位於 Windows 應用程式專案的 [Bin] 節點中。
注意事項 |
---|
如果您已經在 [顯示所有檔案] 模式下,必須按一下 [檢視] 功能表中的 [重新整理] 重新整理檢視,才能看見檔案。 |
請注意,LoanClass 的三個成員以 XML 格式顯示。 請變更並儲存 XML 檔案中的 InterestRate 值,然後再次執行應用程式。 新利率將隨即出現在第二個文字方塊中。