lunes, 17 de junio de 2013

Seguridad de Tipos en C#

C# es un lenguaje de tipado fuerte. Conceptualmente esto quiere decir que un tipo sólo ofrece a través de una interfaz pública los métodos, propiedades, etc. con los que otros objetos pueden intercambiar mensajes. Para ejemplificarlo, C# asegura que operaciones que se pueden realizar sobre un tipo string estén prohibidas en un tipo primitivo int.

Archivo C# SeguridadDeTipos.cs [enlace alterntivo]:

- ¿Para qué sirve la seguridad de tipos (type safety)?

Robin Milner describe la seguridad de tipos de esta manera: 
«Well-typed programs cannot "go wrong".»
Lo que significa esta frase es que aún cuando el programa se halle en ejecución, debe evitarse que tipos de datos no permitidos sean pasados a las funciones, por ejemplo. Este es un buen principio para la escritura de programas lógicamente correctos y perdurables a lo largo del tiempo de su uso.

- Relación con tipeo estático (static typing)

El tipeo estático forza que las reglas de tipos se comprueben en tiempo de compilación [2]. Esto sigue el slogan de Robin Miller mencionado arriba; por lo tanto nos asegura programas correctos antes de que pasen a tiempo de ejecución con errores de casting (conversión explícita o implícita de tipos). El compilador de C# sigue este principio, haciéndolo expresivo, y guía al programador a cumplir reglas sintácticas del lenguaje.

- Ventajas de un lenguaje con seguridad de tipos:

La seguridad de tipos de C# elimina errores como: 
  • Operaciones ilegales: las reglas aritméticas en C# están correctamente definidas (gracias a Turing completo [4], lo que significa que cualquier función matemática puede ser calculada), pero al operar, por ejemplo: 3 / "cadena de texto", se generará un error antes de que el programa pase a ejecutarse. En el ejemplo que viene a continuación, la operación int division = enteroSimple / cadenaDeTexto; generará el siguiente mensaje de error de tipeo: Operator '/' cannot be applied to operands of type 'int' and 'string' .
Archivo C# OperacionesIlegales.cs [enlace alternativo]:
  • Seguridad de memoria (memory safety): 
    • Wild pointers [5]: Aunque el manejo de direcciones de memoria es transparente en un lenguaje de alto nivel como C#, es importante mencionar los problemas/errores de seguridad de tipeo relacionados con la manipulación de punteros, sobretodo en situaciones que se trate una dirección de memoria con un de puntero no inicializado o de tipo diferente.
    • Desbordamiento de búfer: A nivel de asignación de memoria para un objeto en el heap, se presenta un buffer overflow o buffer overrun cuando un objeto de mayor tamaño (el espacio en memoria) pretende ser copiado en una locación de un objeto de menor tamaño.
  • Errores lógicos: Este tipo de errores resultan muy difíciles de detectar por el analizador semántico del compilador de C#, por ejemplo, en la conversión de unidades medidas, así:
- Static typing vs dynamic typing:

Si empezamos por mostrar un ejemplo en un lenguaje débilmente tipeado, como PHP:


Archivo PHP TipeadoDebil.php [enlace alternativo]:
Los tipos de valores que almacena la variable $variable no están sujetos a pruebas de validación o comprobación a medida que se interpreta el programa, pero si esto se analoga en C#, tenemos:

Archivo C# StaticVsDynamic.cs [enlace alternativo]:
En tiempo de compilación, en la línea 7 el compilador detectará el siguiente error: Cannot implicitly convert type 'int' to 'string'.  Entonces a diferencia de un lenguaje dinámico como PHP, C# cuida las reglas de conversión, tratamiento de tipos de datos en tiempo de compilación, mientras que PHP lo hace en tiempo de ejecución (de ahí que sea un lenguaje interpretado). Adicionalmente, el tipeo estático es reconoce más errores en tiempo de compilación [2].

- Herramienta de Visual Studio: IntelliSense:


La seguridad de tipos facilita a herramientas tales como IntelliSense (la cual viene integrada en Visual Studio) reconocer los protocolos, es decir, las capacidades del tipo del objeto, i.e., al tratar un objeto de tipo string, IntelliSense nos ofrece una lista de métodos, propiedades especificados en la clase del tipo, así:


- Dinamismo en C#:

En su naturaleza, C# es un lenguaje de programación de tipeado estático, sin embargo la especificación del lenguaje permite introducir código de tipeado dinámico. A continuación un ejemplo de su uso:
- El código de C# corre sobre sandbox:

En breve, otra de las características que agrega una capa de seguridad a las aplicaciones creadas en C# es el sandbox, donde las reglas de acceso a recursos del entorno exterior de la aplicación son impuestas por el sistema anfitrión.

- Conclusiones:

Debido a la naturaleza de lenguaje fuertemente tipeado que posee C#, es importante haber reconocido el significado y la importancia de la seguridad de tipos a la hora de escribir programas en este lenguaje y sobre el impacto en la robustez y exactitud de la aplicación. Otro elemento es static typing: la comprobación que realiza el compilador para asegurar el uso correcto de tipos antes de pasar a tiempo de ejecución. También se exploraron las ventajas de la seguridad de tipos: eliminación de operaciones no permitidas, manejo seguro de memoria, y el llamado al programador a atender problemas lógicos en el diseño de algoritmos.

Glosario:

- IntelliSense.
- Type safety. 
- Fisura en la seguridad.
- Wild pointer.
- Buffer overrun.
- Dynamic typing.
- Static typing.

Referencias:

[1] Type safety - http://en.wikipedia.org/wiki/Type_safety

[2] Static typing - http://www.diclib.com/static%20typing/show/es/en_foldoc/12410
[3] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[4] Turing completo - http://es.wikipedia.org/wiki/Turing_completo
[5] Wild pointer - http://en.wikipedia.org/wiki/Wild_pointer


J

No hay comentarios:

Publicar un comentario

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