jueves, 10 de octubre de 2013

Propiedades en C#

Tabla de Contenido

0. Introducción
1. Propiedades en C#
2. Propiedades vs Campos de Instancia
3. Propiedades Sólo-Lectura y Calculadas
4. Propiedades Automáticas
5. Accesibilidad de Propiedades de Acceso y Mutación
6. Herencia y Propiedades
7. Implementacion de las Propiedades por la CLR
8. Conclusiones
9. Glosario
10. Enlaces & Literatura

0. Introducción

En lenguajes de programación como Java solemos escribir los métodos de acceso y mutación de los campos de la clase. La forma convencional consiste en anteponer los prefijos get- y set- para referirse a los métodos de acceso y a los métodos de mutación, respectivamente. Este mismo esquema de estructura de los tipos para los miembros puede utilizarse en C#, sin embargo, este lenguaje provee un mecanismo más natural de acceder y cambiar valores de los campos; me refiero a las propiedades.

1. Propiedades en C#

Semánticamente las propiedades se analogan con los campos miembro de un tipo, sin embargo, las propiedades permiten hacer validaciones sobre las asignaciones y mantener la consistencia de los datos asignados a los campos miembro (o de instancia). Las propiedades, además, a nivel sintáctico difieren notablemente debido a la forma de su declaración y composición estructural:

Campo:

private string Nombre;

Propiedad:

private string Nombre
{
get;
set;
}

Nótese de la diferencia de la sintaxis requerida para construir cada uno de estos miembros de instancia. Por un lado, el campo sólo requiere (elementalmente) de tres elementos: 

modificador de acceso + tipo de dato + identificador;

la propiedad por su lado, además de la sintaxis anterior requiere especificar un bloque de código encerrado entre llaves de apertura ({) y cierre (}). En el bloque de construcción se especifica la combinación de acceso y modificación a través de set y get.

Por otro parte, [1] si quisiéramos distinguir entre una propiedad y un cambo desde código cliente no podríamos saberlo (bueno sí, pero si utilizamos un editor de código fuente como el que incorpora Visual Studio):
Distintinción entre propiedades y campos en Visual Studio.
Figura 1. Distinción gráfica entre Campos y Propiedades en Visual Studio 2012.
Para los campos o variables se utiliza el ícono (aquí Apellido):
Ícono de Babel para campos y variables.
Para las propiedades (en este ejemplo Edad y Nombre):
Ìcono de Babel para propiedades.
[Nota: En [2] se encuentra el listado de los íconos de Babel (Babel icons) para Visual Studio; en [3] para la versión de Visual Studio 2008.]

1.1 Construcciones de Acceso

Una propiedad está compuesta por los elementos de acceso: get y set.

1.1.1 get

A través de get podemos acceder al valor de la propiedad, en consecuencia del campo asociado con esta propiedad. El valor de retorno corresponde con el tipo de la propiedad. Cuando sólo especificamos esta construcción en el cuerpo de una propiedad, decimos que la propiedad es de sólo lectura.

1.1.2 set

En otros lenguajes se le conoce como mutador, debido a que es la construcción de acceso que modifica, cambia o muta el valor del campo asociado con la propiedad. Cuando sólo se ha especificado set en el cuerpo de la propiedad, decimos que se trata de una propiedad de sólo escritura. Adicionalmente, esta construcción de acceso tiene una variable implícita llamada value que corresonde con el valor a asignar a la propiedad.


Las construcciones de acceso se pueden combinar para crear propiedades de lectura y escritura como ocurre en:

private string Nombre
{
get;
set;
}

Parar agregar, vale decir que las propiedades permiten al programador crear lógica de validacion para la asignación de valores. Esto va a permitir mantener el estado del objeto consistente, es decir, dentro del dominio de valores o estados permitidos a partir del modelo del mundo del problema. Veremos más adelante que es posible controlar los datos inválidos por medio del lanzamiento de excepciones.

Finalmente, las propiedades permiten la siguiente lista de modificadores [1]:
Modificadores de las propiedades en C#.
Figura 1. Modificadores de propiedades en C# [1].

2. Propiedades vs. Campos de Instancia

Las diferencias entre propiedades y campos de instancia que se presentan a continuación son tomadas desde [4]. Aquí se hará la mejor traducción e interpretación posible:
  1. Los campos pueden ser usados como argumentos que aceptan las variantes out y ref (ver artículo Variables y Parámetros en C# - Parte 2 | Experiencias Construcción Software).
  2. Las propiedades pueden lanzar excepciones, mientras que los campos no.
  3. Las propiedades aceptan el modificador de herencia virtual, lo que permite ser sobreescritas en tipos descendientes.
  4. El compilador JIT de la CLR trata de manera diferente las propiedades de los campos.
  5. Con las propiedades podemos tener diferentes niveles de acceso: sólo lectura, sólo escritura, o lectura y escritura.

3. Propiedades de Sólo-Lectura

Las propiedades de sólo-lectura son aquellas de las cuales sólo podemos obtener el valor a través de la construcción sintáctica de acceso get. Si en lugar, sólo especificamos la construcción sintáctica de mutación set entonces tenemos una propiedad de sólo escritura.

Una situación ejemplar en la que se utilice la propiedad de sólo lectura es la de cálculo de los valores de los campos de instancia. Así:

private decimal precio;
private int cantidad;

private decimal SubTotal
{
get
{
return precio * cantidad;
}
}

Esta propiedad SubTotal es de sólo lectura, pues sólo posee get en su cuerpo de declaración.

4. Propiedades Automáticas

Una propiedad automática es el resultado de la declaración de una propiedad que genera de forma automática un campo de instancia no manipulable en tiempo de compilación. El campo no tendrá visibilidad en código ni tampoco desde las clases cliente.

Miremos esta clase de ejemplo:

Archivo C# Producto.cs [enlace alternativo]:
La declaración de la propiedad PrecioActual en la línea 3 implícitamente cuando sea compilada esta clase se generará un backing field (campo de instancia) como se describió anteriormente.

De acuerdo con [1], la construcción de mutación set puede ser marcada con el modificador de acceso private.

[Nota: Las propiedades automáticas fueron introducidas en la versión 3.0 de C#.]

5. Accesibilidad de Propiedaes de Acceso y Mutación

Las construcciones get y set pueden ser alteradas con los modificadores de acceso internal y private.

Archivo C# Empleado.cs [enlace alternativo]:

Cuando tratemos de compilar estas clases, se generará el siguiente mensaje de error:


error CS0272: The property or indexer `PruebaAccesibilidad.Empleado.Nombre' cannot be used in this context because the set accessor is inaccessible

6. Herencia y Propiedades

En el punto 2 se enunciaron varias de las diferencias entre los campos de instancia y las propiedades, aprovecharemos aquí más para describir más a fondo la facilidad que brindan las propiedades en el mecanismo de herencia en C#.

La demostración se hará a partir del siguiente ejemplo (basado en el diagrama de clases de la Figura 2):
Jerarquía de Herencia Figura
Figura 2. Diagrama herarquía de herencia.

Archivo C# Figura.cs [enlace alternativo]:
Archivo C# Cuadrado.cs [enlace alternativo]:
Archivo C# Circulo.cs [enlace alternativo]:
Archivo C# Rectangulo.cs [enlace alternativo]:
Y finalmente, la clase de prueba:

Archivo C# PruebaFigura.cs [enlace alternativo]:
► Prueba de ejecución.

6. Implementación de las Propiedades por la CLR

Las propiedades creadas en código fuente C# el compilador las transforma a métodos del estilo:
  • get_XXX
  • set_XXX
Por ejemplo:

public decimal get_PrecioActual ()
{
//...
}

public void set_PrecioActual (decimal valor)
{
//...
}

Además, el compilador JIT se encargará de realizar optimizaciones sobre el código generado para las métodos resultantes de las propiedades.

7. Conclusiones

A lo largo de este artículo hemos aprendido acerca del uso y utilidad de las propiedades en C#. A través de ejemplos sencillos se ha demostrado la sintaxis necesaria para componer una propiedad y cómo asignar o recuperar un valor. Se ennumeraron algunas diferencias entre las propiedades y los campos de instancia; e inclusive se presentó un ejemplo demostrado la capacidad de las propiedades en el mecanismo de herencia. Al final se demostró la representación de la compilación de las propiedades: se trata de métodos de la forma get_XXX y set_XXX.

8. Glosario

  • get
  • JIT
  • Mutación
  • Propiedad
  • set

9. Enlaces & Literatura

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Class View and Object Browser Icons - http://msdn.microsoft.com/en-us/library/y47ychfe.aspx
[3]: Babel Icons - http://msdn.microsoft.com/en-us/library/bb166402%28v=VS.90%29.aspx
[4]: properties - Difference between Property and Field in C# 3.0+ - Stack Overflow http://stackoverflow.com/questions/653536/difference-between-property-and-field-in-c-sharp-3-0


O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.