September 2009 - Artículos


Supongo que a estas alturas ya todos los sabréis, y es que varios grupos de usuarios de España y uno (el único) de Andorra se han empeñado en hacer un evento gratuito y tecnológico que a mi modo de ver ha ido creciendo enormemente hasta lograr ser un evento más que recomendable y de obligada visita por la variedad de temas interesantes que se van a tratar.
Lo que empezó con interesantes y pequeñas ideas, se ha convertido en el que quizás sea uno de los mejores eventos que sobre tecnología .NET se realicen en España (sin contar el Tech·Ed) en los últimos años.
Muchísimas empresas y profesionales se han mojado, y eso es de agradecer, y las personas que están haciendo posible el evento están dedicando su tiempo y esfuerzos en lograr que esto sea posible, algo que es encomiable.
En mi caso particular, también yo me he mojado (menos de lo que me hubiera gustado), y desde hace bastantes meses ya tenía en mente una sesión, sesión que ya no tiene vuelta atrás y que Dios mediante daré con mis amigos y compañeros Pep Lluis y Lluis Franco, ambos MVP de Visual Basic como yo.
La sesión está catalogada como de nivel 100 (casi todas las sesiones son de nivel 100 y 200), y en ella se tratará de forma rápida la evolución desde VB al comienzo de .NET, para hacer posteriormente un pequeño repaso de las versiones de VB en .NET y pararnos más en algunas de las novedades que trajo VB 2008, y detenernos firmemente en las novedades de VB 2010 que están a punto de aparecer.
La sesión tiene una duración de 1 hora, por lo que estamos obligados a que sea rápida, así que no habrá tiempo de aburrirse. Al final de la sesión tendremos un pequeño apartado para preguntas y respuestas. Si no fuera suficiente o tuvieses o quisieses trasladarnos alguna pregunta, tendremos la posibilidad de realizar preguntas y respuestas fuera de la sesión en áreas habilitadas para ello.
¡Os esperamos!
Referencias:
Acceso directo a la web del evento (CodeCamp Tarragona 2009).
Lugar en el que se realizará el evento.
Sesiones del evento.
Página web para registrarse al evento (gratis).

Microsoft ha sacado hace pocas semanas la versión final de Silverlight 3, y como no... ya están pensando en la versión 4.
Para ello, Microsoft posee un foro destinado a recoger el feedback de los clientes acerca de Silverlight 4.
Si tienes alguna sugerencia que hacer o tienes especial interés en demandar alguna característica que no encuentres en Silverlight, te invito a pasar por el foro (en inglés) y dejar allí tu "perla", o votar por aquellas características que ya han sido solicitadas y que tú consideras muy útil. :-)
Referencias:
Acceso directo al foro de Customer feedback sobre Silverlight 4.

Una de las nuevas características de VB 2010 ó VB 10 es la nueva declaración de lo que son las Propiedades. Dicho de otra forma, las propiedades autoimplementadas.
Ahora, en VB 10 podemos declarar una propiedad de la siguiente forma:
Public Property Name() As String
La discusión más lógica que puede salir de nuestros labios es la que una persona le hizo a Jonathan Aneja (Microsoft y responsable de VB) sobre este asunto.
¿Para qué usar Public Property Name() As String en lugar de Public Name As String?.
Por esa razón, Jonathan ha escrito una entrada en su blog indicando el porqué es mejor usar Properties (Propiedades) en lugar de Fields (Campos), así como sus ventajas.
Os recomiendo la lectura de este artículo en la sección de referencias de esta entrada porque le aclarará a más de uno esas dudas.
No obstante, añadiré algunas anotaciones personales sobre "lo que no se ve", sobre la parte "posterior" de las propiedades autoimplementadas.
Al declarar una propiedad autoimplementada como por ejemplo Public Property Name() As String, en realidad y de cara al compilador, la estaremos declarando como hemos hecho siempre, indicando su Get y su Set.
De hecho, si miramos el código en Reflector, veremos que éste tiene el siguiente aspecto:
Public Property Name As String
Get
Return Me._Name
End Get
Set(ByVal AutoPropertyValue As String)
Me._Name = AutoPropertyValue
End Set
End Property
Curiosamente, el compilador se ha encargado de crear las propiedades en su manera general, e implícitamente una variable privada que permita almacenar y establecer el valor de la propiedad:
<CompilerGenerated, DebuggerBrowsable(DebuggerBrowsableState.Never)> _
Private _Name As String
Ahora bien, ¿qué ocurre si definimos una variable del tipo Private _Name As String?.
En este caso el compilador tiene un problema, ya que internamente, la propiedad Name define implícitamente a _Name, y por sí solo, es incapaz de definir implícitamente a otra variable.
De hecho, el compilador de Visual Studio 2010 indica en tiempo de diseño el siguente mensaje de error:
property 'Name' implicitly defines '_Name', which conflicts with a member of the same name in class 'Form1'.
Esto es así porque el compilador de Visual Basic declara implícitamente a las variables de las propiedades con el caracter de subrayado seguido del nombre de la propiedad.
Comento esto para que únicamente se tenga en cuenta cuando trabajemos con Visual Basic 2010, y por si a alguien se le ocurre declarar variables con el caracter subrayado delante del nombre de la declaración, para que no lo hagan porque no sería una buena práctica de acuerdo a lo que hace "por debajo" el compilador. ;-)
Referencia:
Acceso directo a la entrada de Jonathan Aneja.

Me encuentro en el blog de Damien Guard una interesante chuleta o cheat sheet sobre LINQ to SQL con atajos en C# y VB.
Encuentro especialmente útil tener a mano la chuleta sobre todo para aquellos que comienzan con LINQ2SQL.
Referencias:
Blog de Damien Guard.
Acceso directo a la chuleta de LINQ2SQL.

Muchos programadores saben que cuando creamos una clase, ésta puede ser serializada o no (marshalling).
La serialización permite codificar un objeto para que éste sea enviado por un canal de comunicaciones, persistido, o almacenado en un medio físico (base de datos, fichero, envío por mail, etc).
La idea es que el objeto sea transmitido o consumido por el mismo o por otro proceso.
Para entender este planteamiento, pongamos un ejemplo teórico de esta filosofía de trabajo.
Tenemos un objeto con unas propiedades. Asignamos valores a las propiedades y persistimos los datos en memoria.
Una vez que tenemos los datos definitivos en memoria, persistimos físicamente los datos en un fichero en disco.
Otro proceso, se encargará de leer la información del fichero en disco y convertirla nuevamente a un objeto del mismo tipo que el original para crear una copia idéntica de los datos que se persistieron, de manera tal que podamos trabajar con los mismos datos que teníamos previamente en memoria.
El planteamiento teórico marcado quedaría resumido con el siguiente gráfico:

Si alargamos este proceso en el tiempo o si pensamos en sistemas geográficamente separados, entenderemos que la persistencia de información puede resultar muy útil.
Un ejemplo de utilidad de persistencia de información la podemos encontrar en los flujos de datos o workflows o en los envíos de datos y objetos por redes.
Ahora bien, ¿cómo llevar a cabo la persistencia de datos de forma práctica?.
Crearemos una aplicación dentro de la cual insertaremos tres (3) controles Label, tres (3) controles TextBox, y dos (2) controles Button.
La idea es que al iniciarse la aplicación, se cree un objeto determinado y lea sus datos por defecto presentándolos por pantalla.
El usuario podrá modificar los datos que considere oportuno y pulsar el control Button para persistir la información en disco.
Una vez hecho esto, la misma aplicación será capaz de abrir el fichero con el objeto persistido. Para ello, pulsaremos el segundo control Button que se encargará de realizar esta acción.
El código de la aplicación viene totalmente comentado y creo que es lo suficientemente clarificador por sí solo.
Por un lado, crearemos la clase de nombre Product:
''' <summary>
''' Clase Product encargada de almacenar la informacide un producto.
''' Esta información puede ser serializada y persistida.
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class Product
#Region "VARIABLES"
''' <summary>
''' Variable que almacena el nombre del producto.
''' </summary>
''' <remarks></remarks>
Public Name As String = ""
''' <summary>
''' Variable que almacena la cantidad pedida.
''' </summary>
''' <remarks></remarks>
Public Quantity As Double = 100.0
''' <summary>
''' Variable que indica el impuesto aplicable al producto.
''' </summary>
''' <remarks></remarks>
Public Tax As Double = 16.0
#End Region
#Region "CONSTRUCTORS"
''' <summary>
''' Clase del constructor.
''' </summary>
''' <remarks></remarks>
Public Sub Product()
End Sub ' Product Constructor
''' <summary>
''' Clase del constructor.
''' </summary>
''' <param name="name"></param>
''' <param name="quantity"></param>
''' <param name="tax"></param>
''' <remarks></remarks>
Public Sub Product(ByVal name As String, ByVal quantity As Double, ByVal tax As Double)
Me.Name = name
Me.Quantity = quantity
Me.Tax = tax
End Sub ' Product Constructor
#End Region
End Class ' Product Class
Por otro lado, crearemos nuestra aplicación Windows de prueba:
Option Strict On
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
''' <summary>
''' Clase del formulario principal de la aplicacion.
''' </summary>
''' <remarks></remarks>
Public Class MainForm
#Region "PROPERTIES"
''' <summary>
''' Variable local utilizada para la propiedad File.
''' </summary>
''' <remarks></remarks>
Private m_FileName As String
''' <summary>
''' Propiedad File para almacenar la ruta y fichero en
''' el cual se persisitira la informacion.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Private Property FileName() As String
Get
Return m_FileName
End Get
Set(ByVal value As String)
m_FileName = value
End Set
End Property
#End Region
#Region "MainForm"
''' <summary>
''' MainForm_Load que se lanza al ejecutarse la aplicacion.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Indicamos la ruta y nombre del fichero a persistir.
Me.FileName = "D:\TEMP\ProductClass.dat"
' Declaramos la clase.
Dim clase As New Product()
' Llamamos al metodo que se encarga de mostrar los datos
' de la clase por pantalla.
ShowDataProduct(clase)
End Sub
#End Region
#Region "METHODS"
''' <summary>
''' Mencargado de mostrar los datos en pantalla de un objeto Product.
''' </summary>
''' <param name="product">Clase Product con la informacion a mostrar.</param>
''' <remarks></remarks>
Private Sub ShowDataProduct(ByVal product As Product)
' Mostramos el nombre del producto.
Me.txtName.Text = product.Name
' Mostramos la cantidad solicitada para ese producto.
Me.txtQuantity.Text = product.Quantity.ToString()
' Mostramos el impuesto asociado al producto.
Me.txtTax.Text = product.Tax.ToString()
End Sub
#End Region
#Region "EVENTS"
''' <summary>
''' Evento lanzado al hacer clic sobre el boton de persistir la informacion.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnPersist_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPersist.Click
' Declaramos un objeto Product.
Dim product As New Product()
' Indicamos el nombre del producto.
product.Name = Me.txtName.Text
' Indicamos la cantidad de productos solicitados.
product.Quantity = Convert.ToDouble(Me.txtQuantity.Text)
' Indicamos el impuesto a aplicar al producto.
product.Tax = Convert.ToDouble(Me.txtTax.Text)
' Declaramos un objeto de tipo Stream y creamos el fichero
' para escribir o serializar la informacion sobre el.
Using fileStream As FileStream = File.Create(Me.FileName)
' Declaramos un objeto de tipo BinaryFormatter.
Dim persist As New BinaryFormatter()
' Serializamos los datos y los persistimos
' sobre el fichero que hayamos indicado.
persist.Serialize(fileStream, product)
' Mostramos un mensaje en pantalla indicando
' que se ha realizado la accion.
MessageBox.Show("Los datos han sido persistidos correctamente.")
End Using
End Sub
''' <summary>
''' Evento lanzado al hacer clic sobre el boton de obtener la informacion persistida.
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnReadObject_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReadObject.Click
' Si existe el fichero persistido, realizados la accion de
' recuperacion de sus datos y mostrarlos en pantalla.
If (File.Exists(Me.FileName)) Then
Try
' Declaramos un objeto Product.
Dim product As New Product()
' Declaramos un objeto de tipo Stream y leemos el fichero
' que contiene la informacion persistida.
Using fileStream As FileStream = File.OpenRead(Me.FileName)
' Declaramos un objeto de tipo BinaryFormatter.
Dim persist As New BinaryFormatter()
' Obtenemos los datos persistidos y los deserializamos.
product = CType(persist.Deserialize(fileStream), Product)
' Llamamos al metodo que se encarga de mostrar los datos
' de la clase por pantalla.
ShowDataProduct(product)
' Mostramos un mensaje en pantalla indicando
' que se han lelos datos persistidos.
MessageBox.Show("Datos persistidos leidos correctamente.")
End Using
Catch ex As Exception
' Mostramos un mensaje en pantalla indicando
' que se ha producido un error.
MessageBox.Show("Se ha producido un error a la hora de leer la informacion persistida." & _
Environment.NewLine & _
Environment.NewLine & _
"Mensaje original del error:" & _
Environment.NewLine & _
ex.Message.ToString())
End Try
Else
' Mostramos un mensaje en pantalla indicando
' que se no se han encontrado datos persistidos.
MessageBox.Show("No se ha encontrado ninguna informacion persistida.")
End If
End Sub
#End Region
End Class ' MainForm Class
En el código, se utilizan los namespaces System.IO (utilizado para escribir y leer el fichero con información persistida a través de la clase Stream) y System.Runtime.Serialization.Formatters.Binary (utilizado para serializar y deserializar la información del objeto a través de la clase BinaryFormatter).
Nuestra aplicación en ejecución tendrá el siguiente aspecto:

Si quieres acceder al código de la aplicación, lo podrás hacer en este enlace (25 Kb):
Acceso directo al ejemplo (25 Kb).