Tutorial: Conservar un objeto (C# y Visual Basic)
Aunque en tiempo de diseño se pueden establecer las propiedades de un objeto en valores predeterminados, cualquier valor introducido en tiempo de ejecución se pierde cuando se destruye el objeto. Puede usar la serialización para conservar los datos de un objeto entre las instancias, lo que permite almacenar valores y recuperarlos la próxima vez que se cree una instancia del objeto.
Nota
En Visual Basic, para almacenar datos simples, como un nombre o un número, puede usar el objeto My.Settings. Para obtener más información, vea My.Settings (Objeto) (Visual Basic).
En este tutorial, creará un objeto Loan simple y guardará sus datos en un archivo. Recuperará a continuación los datos del archivo al volver a crear el objeto. Por último, modificará el código para almacenar el objeto con un formato SOAP.
Nota sobre la seguridad |
---|
En este ejemplo se crea un nuevo archivo, si es que aún no existe. Si una aplicación debe crear un archivo, necesitará tener permisos Create en la carpeta correspondiente. Los permisos se establecen usando listas de control de acceso. Sin embargo, si el archivo ya existe, la aplicación sólo precisará el permiso de Write, un permiso menor. Por tanto, siempre que sea posible, resulta más seguro crear el archivo durante la implementación y conceder sólo permisos Read a un único archivo (en lugar de conceder permisos Create a una carpeta). También es más seguro escribir datos en carpetas de usuario en lugar de en la carpeta raíz o en la carpeta Archivos de programa. |
Nota sobre la seguridad |
---|
En este ejemplo se almacenan datos en un formato de archivo binario o SOAP. Estos formatos no se deben usar con datos confidenciales, como contraseñas o información de la tarjeta de crédito. |
Nota
Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la Ayuda, en función de los valores de configuración o de edición activos. Para cambiar su configuración, haga clic en Importar y exportar configuraciones en el menú Herramientas. Para obtener más información, vea Valores de configuración de Visual Studio.
Crear el objeto Loan
El primer paso consiste en crear una clase Loan y una aplicación de prueba que utilice esta clase.
Para crear la clase Loan
Cree un nuevo proyecto Biblioteca de clases y denomínelo "LoanClass". Para obtener más información, vea Cómo: Crear soluciones y proyectos.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en el archivo Class1 y, a continuación, haga clic en Cambiar nombre. Cambie el nombre del archivo a Loan y, a continuación, presione ENTRAR. Al cambiar el nombre del archivo también se cambiará el nombre de la clase a Loan.
Agregue a la clase los miembros públicos siguientes:
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; } }
También tendrá que crear una aplicación simple que utilice la clase Loan.
Para crear una aplicación de prueba
Para agregar a la solución un proyecto de aplicación de Windows Forms, en el menú Archivo, elija Agregar y, a continuación, haga clic en Nuevo proyecto.
En el cuadro de diálogo Agregar nuevo proyecto, escriba LoanApp como el nombre del proyecto y haga clic en Aceptar para cerrar el cuadro de diálogo.
En el Explorador de soluciones, seleccione el proyecto LoanApp.
En el menú Proyecto, haga clic en Establecer como proyecto de inicio.
Haga clic en la opción Agregar referencia del menú Proyecto.
En el cuadro de diálogo Agregar referencia, haga clic en la ficha Proyectos y seleccione el proyecto LoanClass.
Haga clic en Aceptar para cerrar el cuadro de diálogo.
En el diseñador, agregue cuatro controles TextBox al formulario.
En el Editor de códigos, agregue el siguiente código:
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; }
Agregue al formulario un controlador de eventos para el evento PropertyChanged mediante el siguiente código:
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."); }
Llegado este punto, puede generar y ejecutar la aplicación. Observe que los valores predeterminados de la clase Loan aparecen en los cuadros de texto. Pruebe a cambiar el valor del tipo de interés de 7,5 a 7,1 y, a continuación, cierre la aplicación y ejecútela de nuevo; el valor vuelve a ser el predeterminado de 7,5.
En el mundo real, los tipos de interés cambian periódicamente, pero no forzosamente cada vez que se ejecuta la aplicación. En lugar de hacer que el usuario actualice el tipo de interés cada vez que se ejecute la aplicación, sería mejor guardar el tipo de interés más reciente entre las instancias de la aplicación. En el paso siguiente, hará exactamente eso agregando la serialización a la clase Loan.
Usar serialización para guardar el objeto
Para guardar los valores de la clase Loan, primero debe marcarse la clase con el atributo Serializable.
Para marcar una clase como serializable
Cambie la declaración de la clase Loan del modo siguiente:
<Serializable()> Public Class Loan
[Serializable()] public class Loan : System.ComponentModel.INotifyPropertyChanged {
El atributo Serializable indica al compilador que todo el contenido de la clase se puede guardar en un archivo. Dado que el evento PropertyChanged lo controla un objeto de Windows Forms, no es posible serializarlo. El atributo NonSerialized se puede utilizar para marcar miembros de clase que no deberían guardarse.
Para evitar que un miembro se serialice
Cambie la declaración del evento PropertyChanged del modo siguiente:
<NonSerialized()> Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler _ Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
[field: NonSerialized()] public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
El paso siguiente es agregar el código de serialización a la aplicación LoanApp. Para serializar la clase y escribirla en un archivo, utilizará los espacios de nombres System.IO y System.Xml.Serialization. Para evitar que tenga que escribir nombres completos, puede agregar referencias a las bibliotecas de clases necesarias.
Para agregar referencias a espacios de nombres
Agregue las siguientes instrucciones al principio de la clase Form1:
Imports System.IO Imports System.Runtime.Serialization.Formatters.Binary
using System.IO; using System.Runtime.Serialization.Formatters.Binary;
En este caso, está usando un formateador para guardar el objeto en un formato binario. Más adelante en este tutorial modificará el código para guardar el objeto en un formato SOAP.
El paso siguiente es agregar código para deserializar el objeto del archivo cuando se cree.
Para deserializar un objeto
Agregue una constante a la clase para el nombre de archivo de datos serializados.
Const FileName As String = "..\..\SavedLoan.bin"
const string FileName = @"..\..\SavedLoan.bin";
Modifique el código del procedimiento de evento Form1_Load del modo siguiente:
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; }
Observe que primero tiene que comprobar que el archivo existe. Si es así, cree una clase Stream para leer el archivo binario y una clase BinaryFormatter para traducirlo. Asimismo, deberá convertir el tipo de la secuencia en el tipo del objeto Loan.
A continuación, tiene que agregar código para guardar los datos introducidos en los cuadros de texto de la clase Loan y, a continuación, debe serializar la clase en un archivo.
Para guardar los datos y serializar la clase
Agregue el siguiente código al procedimiento de evento 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(); }
Llegado este punto, puede volver a generar y ejecutar la aplicación. Inicialmente, los valores predeterminados aparecen en los cuadros de texto. Pruebe a cambiar los valores e introducir un nombre en el cuarto cuadro de texto. Cierre la aplicación y, a continuación, ejecútela de nuevo. Observe que los nuevos valores aparecen ahora en los cuadros de texto.
Guardar el objeto con un formato SOAP
En este ejemplo se ha mostrado hasta ahora cómo guardar un objeto en un archivo de texto usando un formato binario, que resulta correcto para la mayoría de las aplicaciones Windows; sin embargo, para las aplicaciones web o los servicios Web, es conveniente guardar el objeto en un archivo XML con un formato SOAP, lo que facilita el uso compartido del objeto.
Para guardar el objeto en un formato SOAP, primero debe hacerse referencia a la clase SoapFormatter. La clase SoapFormatter reside en su propio espacio de nombres: System.Runtime.Serialization.Formatters.Soap.
Para guardar el objeto con un formato SOAP
En el Explorador de soluciones, seleccione el proyecto LoanApp.
Haga clic en la opción Agregar referencia del menú Proyecto.
En el cuadro de diálogo Agregar referencia, haga clic en la ficha .NET y seleccione el componente System.Runtime.Serialization.Formatters.Soap.
Haga clic en Aceptar para cerrar el cuadro de diálogo.
En el Editor de código, agregue la siguiente instrucción al principio del módulo Form1:
Imports System.Runtime.Serialization.Formatters.Soap
using System.Runtime.Serialization.Formatters.Soap;
Cambie el nombre de archivo de SavedLoan.bin a SavedLoan.xml.
En el procedimiento de evento Form1_Load, cambie la declaración de la variable deserializer a:
Dim deserializer As New SoapFormatter
SoapFormatter deserializer = new SoapFormatter();
En el procedimiento de evento Form1_FormClosing, cambie la declaración de la variable serializer a:
Dim serializer As New SoapFormatter
SoapFormatter serializer = new SoapFormatter();
Llegado este punto, puede generar y probar la aplicación. La primera vez que ejecute la aplicación, se creará el archivo SavedLoan.xml. Para ver el archivo, elija la opción Mostrar todos los archivos en el Explorador de soluciones; se encuentra en el nodo Bin del proyecto de aplicación para Windows.
Nota
Si ya se encuentra en el modo Mostrar todos los archivos, para ver el archivo tendrá que actualizar la vista; para ello, seleccione Actualizar en el menú Ver.
Observe que los tres miembros de la clase LoanClass se muestran en formato XML. Cambie el valor de InterestRate en el archivo XML, a continuación guárdelo y ejecute la aplicación de nuevo. El nuevo tipo de interés aparecerá en el segundo cuadro de texto.