C# 3.0. Nuevas características I

Introducción

matrix_ico.jpg Vale, se que esto viene un poco tarde puesto que lleva mucho tiempo en el mercado ya, y no digamos como beta, de hecho Monet, la librería de plugins que creé hace un tiempo, ya utiliza algunas de dichas características.

Visto por encima podemos decir que C# 3.0 proporciona los siguientes "avances" o "facilidades" nuevas:

  • Propiedades automáticas.
  • Inicializadores de objeto y de colecciones (Object & Collections Initializers)
  • Extensiones (Extension Methods)
  • Expresiones Lambda
  • LinQ

En este primer post solo voy a cubrir las dos primeras partes, en un segundo hablaré de las extensiones y ya en el tercero os hablaré de las maravillas de las lambda expressions y el LinQ.

El misterio del bloque try vacio

El misterio

Hace bien poco he leido un interesante artículo (en inglés) llamado "The empty try block mystery" que describe algunas secciones de código presentes en el código fuente del .NET Framework y que son similares a lo siguiente:

try
{
}
finally
{
  HazCosas1();
  HazCosas2();
}

y que responde a la pregunta ¿porque diablos iba alguien a declarar un bloque try finally estando el try vacío? Pues vamos a explicarlo, en español ;)

Introducción a Parallel Extensions. Parte I

Introducción

Parallel Extensions es un framework de Microsoft, aún en desarrollo para facilitar el desarrollo de aplicaciones concurrentes. Recientemente acaban de sacar la primera CTP (comunity tecnology preview) que está disponible para descarga y han solicitado feedback y comentarios en sus foros.

El funcionamiento es el común de una biblioteca, pero la implementación incorpora optimizaciones para mejorar el rendimiento de las aplicaciones multihilo liberando al programador de la tarea. Internamente se encarga de "decidir" si un trabajo debe ser ejecutado en un hilo separado o si se debe ejecutar en el propio hilo que invoca la llamada. Internamente está organizado en una serie de hilos, parecido al thread pool de .NET pero con ciertas optimizaciones, ya que existen una serie de colas internas en las que se insertan los trabajos (es algo más complicado que eso pero baste la simplificación), permitiendo que determinados hilos se "roben" las tareas entre ellos para mejorar la ocupación general de la CPU y por tanto el rendimiento del programa.

La base

Parallel.For

La base de funcionamiento de la librería está centrada en la existencia de una clase estática llamada Parallel que aglutina toda la funcionalidad de la librería, mediante funciones como Parallel.For, Parallel.ForEach o Parallel.Do. Básicamente trata de abordar el cálculo en paralelo de las estructuras For o ForEach. En cuanto a la orden Do, en un momento veremos lo que hace.

Curso de C#. Entrega I. Hola mundo

Introducción

Hola mundo es el programa más típico para empezar un manual. Es una tradición, entre otras cosas por que sirve para empezar por algún punto así como porque toca aspectos básicos para introducir al lenguaje así que, para no variar, es un buen punto de comienzo.

No voy a desarrollar cada uno de los elementos del código sino que consistirá en dos ejemplos simples y luego en entregas posteriores ya iremos examinando los elementos de un programa de forma más detenida.

El código

using System;

namespace HolaMundo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hola mundo");
        }
    }
}

Patrones de diseño. Template Method

Introducción

El patrón de diseño Template Method se utiliza en situaciones en las cuales existe un determinado esqueleto que conforma pasos comunes dentro de un algoritmo o procedimiento en una clase.

Una analogía podría ser la forma en que resolvemos un problema con distintos expertos, por ejemplo, supongamos el caso del ciclo de vida del software (simplificado), que podemos estructurar en los siguientes pasos:

  • Preparar un documento de concepto
  • Elaborar la especificación de requisitos
  • Elaborar el diseño de la aplicación
  • Codificar la solución
  • Realizar las pruebas unitarias
  • Realizar las pruebas de sistema

Ahora bien, el proceso es el mismo cada vez. El documento de concepto puede realizarlo comercial o marqueting, elaborarlo en Word o en PDF. El formato del documento de requisitos puede cambiar o usar un programa de apoyo como DOORS y el código puede realizarse utilizando Delphi, C# o Java, pero el proceso general permanece el mismo, solo cambian los expertos que se encargan de cada cosa.

Distancia geodésica entre dos puntos

Distancia geodésica

Cuando hablamos de la distancia entre dos puntos solemos referirnos a la distancia en linea recta entre esos dos puntos. Sin embargo cuando queremos calcular la distancia entre dos puntos situados sobre una esfera (en mi caso dos puntos sobre la superficie de la tierra) estamos hablando de la distancia geodésica entre esos dos puntos.

Solo pongo esta función aqui porque en el trabajo necesito calcular la distancia geodésica entre dos puntos y estaba usando una librería COM que era excesivamente lenta para lo que necesitaba (4 milisegundos frente a 1 microsegundo). No tengo ni idea de como funciona lo que pongo debajo (si tengo tiempo lo miraré más detenidamente y trataré de explicarlo (hasta donde yo se consiste en aplicar la formula de la longítud de arco de una circunferencia (aplicando además en este caso una desviación, ff, por el achatamiento de la tierra) dadas la latitud y longitud de cada punto)). La función está adaptada de un código de Visual Basic de Jay Tanner para poder usarla en Delphi.

Sistema de plugins con C#. Parte I. Conceptos

Antes de empezar

Un sistema de plugins es un mecanismo complejo. Por un lado el traslado de dependencias hacia el tiempo de ejecución (como veremos más adelante) lo hace mucho más complicado de explicar, de comprender y de implementar. Hay muchas cuestiones a tener en cuenta, este artículo trata de abarcar las principales pero me temo que hay muchas cuestiones que quedarán fuera.

Por otro lado, aunque para entender el sistema no es necesario un conocimiento de .NET o C#, desde luego estos puntos ayudarán a comprenderlo mejor y con más profundidad.

Evidentemente el sistema es demasiado complejo para que explique aquí todas y cada una de las partes que componen el sistema. El código en si, que incluyo en el artículo, está bastante comentado y he procurado ilustrar en el artículo las partes principales del sistema pero no me cabe duda de que habrá zonas que queden sin comentar.

Por último, este es un artículo largo y complejo y aunque he intentado en la medida de lo posible que tanto el código como el artículo esten libre de errores puede que alguno se haya colado, si encontrais alguno o teneis algún comentario os ruego que me lo hagais saber, bien por comentarios o bien directamente contactando conmigo en el email de contacto.

Buffer overflow explicado

Sin duda muchos de vosotros habréis oído hablar de una vulnerabilidad basada en un buffer overflow pero no os ha llegado a quedar claro que significa exactamente esto.

En general, cuando aparecen dichas noticias suelen ir asociadas al término "ejecución de código arbitrario" que es, en realidad, el verdadero problema. Vamos a ver un poco más a fondo lo que significa una vulnerabilidad de buffer overflow y lo que implica.

En primer lugar, la palabra overflow procede del inglés y quiere decir desbordamiento (de hecho existe el término desbordamiento de buffer en español, pero como tantas otras cosas, es mucho más habitual escuchar el término inglés). ¿Que significa esto? Pues ni más ni menos que lo que indica su nombre, que tenemos un buffer cuya capacidad se ha visto desbordada.

En la mayoría de los lenguajes de programación un buffer hace referencia a un puntero a memoria reservada que tiene un determinado tamaño, si intentamos meter datos de más tamaño del del buffer, este se desborda.

Podríamos pensar que cuando esto pasa se produce una excepción y listo (y en algunos lenguajes esto es exactamente lo que pasa) sin embargo en la mayoría de los lenguajes no ocurre, con resultados generalmente desastrosos.

Atributos en .NET. Atributos del framework (I)

ObsoleteAttribute

El atributo "Obsolete" nos permite marcar un elemento de código como obsoleto y asignar un comentario o mensaje de aviso en caso de que se utilice dicho elemento de código. Adicionalmente permite pasar un valor booleano que indique si el atributo se comportará como un error o como un warning.

El uso del atributo resulta útil conforme nuestro código va evolucionado. Quizá una función o una clase que diseñamos hace tiempo para una biblioteca ya no sea la forma más eficiente de hacer las cosas, de forma que queremos sustituir la función o la clase con otra nueva. En este caso el uso del atributo obsolete nos permite mantener la clase o función de forma que un desarrollador que estuviera utilizando la función no se encuentre con que ha desaparecido sin saber por qué sino con un warning (o un error en caso de que así lo hallamos definido) avisándole de que cambie y, preferiblemente, indicándole los pasos a realizar. Vamos a ver un ejemplo muy típico:

[Obsolete("Esta clase esta obsoleta, utilice NuevaFoo en su lugar")]
void Foo(int x)

Atributos en .NET. Leyendo los atributos con Reflection

Table of Contents [hide]

¿Qué es .NET reflection?

La librería reflection de .NET nos va a permitir acceder a la información de los atributos que hemos definido en el artículo anterior.

Reflection es el nombre dado por microsoft al conjunto de utilidades que permite leer la información y metainformación de las dll y ejecutables de .NET en tiempo de ejecución.