viernes, 15 de marzo de 2013

Documentación básica de código

En este artículo veremos la documentación básica que podemos realizar en nuestros proyectos de .NET. Visual Studio nos permite colocar comentarios de documentación para nuestro código colocando etiquetas XML en el código fuente, justo antes del bloque de código al que hará referencia. Por ejemplo:

/// <summary>
/// Este método es realmente soberbio.
/// </summary>
public void MetodoDeEjemplo()
{
    //...código
}
Como todos los comentarios, sean o no de documentación, el compilador simplemente los ignora y por lo tanto no afecta al rendimiento de nuestra aplicación. Los comentarios aplican cobre clases, métodos, estructuras, delegados, interfaces, propiedades, campos, enumeraciones, eventos y muchos otros elementos.  Por ahora nos conformaremos con documentar clases/estructuras, métodos y propiedades (en los métodos se incluyen los constructores) y con los elementos más comunes y relevantes.

Comenzaremos con algo simple, una propiedad. Como mencioné arriba, basta con colocarnos inmediatamente antes de la declaración y poner tres diagonales (///); esta acción es detectada por el IntelligentSense y nos pone las etiquetas de <summary>, esta etiqueta es utilizada para poner una descripción de lo que estamos documentando (una propiedad en nuestro caso) y es usada por el IntelligentSense para mostrar la descripción al momento de estar escribiendo código. Veamos los resultados:

/// <summary>
/// Descripción de la propiedad
/// </summary>
public string Propiedad
{ get; set; }
Usando la propiedad obtenemos este resultado:
Podemos ver subrayado en rojo que el IntelligentSense nos muestra el texto que pusimos dentro de la etiqueta <summary>, de esta forma podemos tener una documentación en nuestro desarrollo y no tener que estar revisando el código para acordarmos lo que hace un método, qué significa cierta propiedad, etc. Esto también es muy util si desarrollamos un módulo que será usado por otras personas para otro desarrollo, nos ahorramos la molestia de que nos pregunten sobre lo que hace tal método, qué representa tal clase, etc.

<summary> es la etiqueta básica para la documentación, pero existen muchas otras. Ahora veamos otro ejemplo más completo con un método:

/// <summary>Este método suma dos enteros</summary>
/// <param name="a">Primer operando</param>
/// <param name="b">Segundo operando</param>
/// <returns>La suma de los operandos</returns>
public int Suma(int a, int b)
{ return a + b; }
De igual manera, al poner las tres diagonales(///) antes de la declaración del método, VisualStudio automáticamente nos coloca las etiquetas de <summary>,<param name=[nombreDelParametro]>, <returns>. Como podrán intuir, las dos etiquetas <param> hacen referencia a los dos parámetros requeridos en el método, y la etiqueta <returns> es para lo que regresa el método (VS no lo coloca cuando el método es void). Veamos el resultado:

Como podemos ver, el IntelligentSense nos muestra la descripción del método y en este caso también el texto que pusimos dentro de <param name="a">, que es el primer parámetro del método. Los mismo ocurre para el parámetro b cuando estemos situados en su posición [p.e. c.Suma(3,)].

Un punto que hay que mencionar es que no vemos nada acerca de lo que pusimos en <returns>. Esta etiqueta no es mostrada por el IntelligentSense, pero es utilizada por el Object Browser de VS; esto toma mucha relevancia cuando nuestro código esta compilado en una DLL y es agregada como referencia en otro proyecto, al usar el Object Browser podemos ver todo lo documentado en nuestra clase.
Y ahí tenemos nuestro texto que escribimos dentro de <returns>.

Además de estas tres etiquetas existen muchas otras (unas visibles para el IntelligentSense y otras no), pero todas nos ayudan para crear una buena documentación de nuestros desarrollos, además de que es posible crear archivos XML con la documentación y crear documentación técnica final usado herramientas como SandCastle. En próximas entregas se abordarán más etiquetas y el uso del SandCastle.

Agradeceré mucho sus comentarios y sugerencias, saludos...
Leonardo Landín
icolandin@gmail.com

viernes, 23 de marzo de 2012

Strings son inmutables

Uno de los interesantes aspectos de la clase System.String es que cuando se le asigna al objeto string su valor inicial, este dato no puede ser cambiado. Esto podría parecer una mentira ya que siempre estmos reasignando strings a nuevos valores y debido también a que System.String define un número de métodos que aparentan modificar el string (como el uppercase y lowercase). Pero si miras mas de cerca lo que ocurre te darás cuenta que los métodos del tipo string de hecho te están regresando un nuevo objeto string. Veamos un ejemplo:




Y aquí estan las pruebas, str1 no fué modificado:




La misma regla de inmutabilidad aplica también para el operador de asignación, veamos este ejemplo:



El codigo anterior no genera salida, pero vamos a ver el código intermedio que generó usando la herramienta ildasm.exe:




No entraré en detalles de lo que significa cada cosa, por ahora nos conformaremos con saber que el código del método StringsInmutables() generó el codigo intermedio que se muestra.

Pongamos atención a las líneas en donde están los strings : "Mi string" y "Mi nuevo string". Si observamos del lado izquiero de cada línea en cuestión vemos que ambas tienen en común la instrucción ldstr. ldstr entendámoslo como la instrucción de cargar un nuevo string (abreviación de load string). Vemos entonces que el primer string "Mi string" queda sin referencia, pues s2 ahora hará referencia al segundo string "Mi nuevo string" y "Mi string" quedará sin referencia ocupando memoria en el heap hasta que el Garbage Collector (GC. Recolector de basura) se ejecute y libere la memoria no utilizada.

Por último, no hay que alarmarse cuando se hacen asignaciones de nuevos strings a una variable pues el GC se ejecuta continuamente, además de que el uso de memoria es mínimo. Los problemas se presentan cuando las asiganciones o concatenaciones (sí, también ocurre en las concatenaciones) son muchas, pues empiezan a saturar el heap y a reducir el performance de nuestra aplicación, en esos casos es preferible usar el StringBuilder.

Espero que este artículo sea de utilidad, agradeceré sus comentarios, y si desean que se aborde sobre el ildasm.exe, StringBuilder o cualquier otro tema de su interés háganlo saber.

Programen felizmente!!!



Leonardo Landín
icolandin@gmail.com

lunes, 12 de marzo de 2012

Un vistazo a los tipos de datos

Hola a todos, en esta entrada se abordan los tipos de datos en C# de manera muy general, pero seguramente habrá una que otra cosita que no sabían acerca de esto; sin mas vueltas entremos en materia.

Como cualquier lenguaje de programación, C# define un conjunto de tipos de datos, los cuales son usados para representar variables, valores de retorno, parámetros, miembros de un objeto, etc. Casi siempre (si no es que siempre), nos referimos a estos tipos de datos por medio de palabras cortas (tokens) que hacen referencia a miembros definidos en el CTS (Common Type System).

En el CTS estan definidos los datos comunes a todo el .NET Framework (C#, VB, F#, etc), es decir, el codigo intermedio generado en C# es el mismo que el que generaría su equivalente en VB, por ejemplo:



int x;        
//es lo mismo que
Dim x as Integer


Ambas instrucciones generan el mismo código intermedio ya que int e Integer son lo mismo en el CTS. Pero en C# también se han definidos tipos de datos exclusivos para este, en la siguiente tabla se muetra cada tipo de dato disponible en C#, su rango, la sintaxis larga y si esta definido en el CTS.


Notación C# cortaEn el CTS?System TypeRangoSignificado en la vida
boolSiSystem.Booleantrue/falseRepresenta verdadero o falso
sbyteNoSystem.SByte-128 a 127Entero de 8 bits con signo
byteSiSystem.Byte0 a 255Entero de 8 bits sin signo
shortSiSystem.Int16-32,768 a 32,767Entero de 16 bits con signo
ushortNoSystem.UInt160 a 65,535Entero de 16 bits sin signo
intSiSystem.Int32-2,147,483,648 a 2,147,483,647Entero de 32 bits con signo
uintNoSystem.UInt320 a 4,294,967,295Entero de 32 bits sin signo
longSiSystem.Int64-9,223,372,036,854,775,808
a 9,223,372,036,854,775,807
Entero de 64 bits con signo
ulongNoSystem.UInt640 a 18,446,744,073,709,551,615Entero de 64 bits sin signo
charSiSystem.CharU+0000 a U+ffffCaracter Unicode de 16 bits
floatSiSystem.Single±1.5 ✕ 10E–45 a ±3.4 ✕ 10E38Número de punto flotante de 32 bits
doubleSiSystem.Double±5.0 ✕ 10E–324 a ±1.7 ✕ 10E308Número de punto flotante de 64 bits
decimalSiSystem.Decimal±1.0 ✕ 10E–28 a ±7.9 ✕ 10E28Número signado de 96 bits
stringSiSystem.StringLimitado por la memoria del sistemaRepresenta un conjunto de caracteres Unicode
ObjectSiSystem.ObjectPuede almacenar cualquier tipo de datos en una variable objetoLa clase base de todos los tipos en el universo del .NET

Cada uno de los tipos numéricos (como int, short, etc.) se asignan a su correspondiente estructura en el System namespace. Estructuras son tipos de valores alojados en el Stack. Por otro lado, string y object son tipos de referencia, lo que significa que son alojados en el Heap. En próximas entregas veremos qué es el Stack y el Heap.



Leonardo Landín
icolandin@gmail.com