martes 26 de julio de 2011

Contratos en C#. Parte 1.

En nuestro libro Algoritmos Objetos y Estructuras de Datos los algoritmos y ejemplos están realizados en C# y Eiffel.
Eiffel tiene el soporte nativo para contratos de software, es el lenguaje pionero en ese sentido. Pero también es posible realizar contratos en C# y en cualquier lenguaje sobre .NET usando  Microsoft Code Contracts.
Code Contracts provee un manera independiente del lenguaje de expresar precondiciones, poscondiciones e invariantes.  Hay algunas diferencias con los contratos en Eiffel fundamentalmente en el tema de la herencia pero igualmente son una poderosa herramienta de construcción de software confiable. Además de la librería hay una serie de herramientas que permiten la verificación de contratos:

  • ccrewrite: permite generar chequeos en tiempo de ejecución para los contratos
  • cccheck un verificador estático de contratos en tiempo de compilación
  • ccdoc que permite agregar los contratos a los archivos de documentación XML
En sucesivos artículos iremos describiendo mas en detalle esta herramienta de contratos de .NET. Para finalizar dejamos el código del ejemplo base de la librería, una clase que representa números racionales. Dicho ejemplo es fácil de leer y de comprender si se conoce el concepto de contratos, mas allá de los detalles de Microsoft Code Contracts.
  public class Rational {
    public int Numerator { get; protected set; }
    public int Denominator { get; protected set; }

    public Rational(int n, int d) {
      Contract.Requires(d != 0);

      this.Numerator = n;
      this.Denominator = d;
    }

    [ContractInvariantMethod]
    private void RationalInvariant() {
      Contract.Invariant(Denominator != 0);
    }

    public virtual void Add(Rational other) {
      Contract.Requires(other != null);
      int newN = this.Numerator * other.Denominator + other.Numerator * this.Denominator;
      int newD = this.Denominator * other.Denominator;

      this.Numerator = newN;
      this.Denominator = newD;
    }

    public static Rational operator +(Rational a, Rational b) {
      Contract.Requires(a != null);
      Contract.Requires(b != null);
      return new Rational(a.Numerator * b.Denominator + b.Numerator * a.Denominator, a.Denominator * b.Denominator);
    }
    public static Rational operator +(Rational a, int b) {
      Contract.Requires(a != null);
      return new Rational(a.Numerator + b * a.Denominator, a.Denominator);
    }

    public virtual void Divide(int divisor)
    {
      Contract.Requires(divisor != 0);

      this.Denominator = this.Denominator * divisor;
    }

    public int Truncate()
    {
      return this.Numerator / this.Denominator;
    }

    public virtual void Invert() {
      Contract.Ensures(Contract.OldValue(this.Numerator) == this.Denominator &&    Contract.OldValue(this.Denominator) == this.Numerator);

      int num = this.Numerator;
      int den = this.Denominator;
      this.Numerator = den;
      this.Denominator = num;
    }

  }

lunes 27 de diciembre de 2010

Ofuscando .NET

La ofuscación de código tiene cómo objetivo proteger la propiedad intelectual del software. Se trata de un proceso por el cual se hace incompresible (o casi) a  los humanos comprender el código.
Dado que es muy fácil transformar el MSIL (el código intermedio que se general al compilar en los lenguajes de .NET y que es luego interpretado por el CLR) en por ejemplo C#, muchos programadores ven la necesidad de proteger su código mediante la ofuscación.
Hay diversas herramientas disponibles en el mercado a diversos precios, afortunadamente existe una herramienta muy potente, que se integra perfectamente con VisualStudio y que es gratuita. Se trata de Eazfuscator.Net.
Una intefaz sencilla y amigable sumado a la posibilidad de lo que se denomina ofuscación declarativa mediante atributos (Declarative Obfuscation Using Custom Attributes).


La figura anterior muestra la forma de ofuscar un proyecto mediante un simple drag and drop.
Para descargarlos, probarlo y ver mas pueden ir a: http://www.foss.kharkov.ua/g1/projects/eazfuscator/dotnet/Default.aspx

miércoles 13 de octubre de 2010

Parámetros Opcionales en C# 4

La nueva versión del lenguaje C# agrega la posibilidad de establecer métodos con parámetros nombrados opcionales. De esta forma puede evitarse tener que definir métodos sobrecargados que en realidad hacen los mismo.

Por ejemplo, para definir un método que recibe un string y un entero podemos tener el siguiente código:

public void recibedos(string cadena, int entero){

…..cuerpo del método

}

Ahora supongamos que queremos que el entero sea optativo. Para ello basta con asignarle un valor por defecto:

public void recibedos(string cadena, int entero=0){

…..cuerpo del método

}

De esta manera podemos invocar

recibedos(“una cadena”);

o

recibedos(“una cadena”, 7);

En el primer caso el parámetro entero toma el valor 0 indicado en su declaración (puede indicarse cualquier valor). En el segundo el parámetro recibe el valor 7.

C# 4 soporta también argumentos nombrados. Algo muy útil cuando se tiene por ejemplo un método como el siguiente:

public void haceralgo(int x=0, int y=1){

….cuerpo del método

}

En este caso tenemos dos parámetros opcionales la x y la y.  Es posible que quiera invocarse el método con sólo un valor para la x, con sólo un valor para y o con ambos o sin ninguno.

haceralgo(x:2);
haceralgo(y:3);
haceralgo(y:2,x:3);
haceralgo();

Todas las invocaciones anteriores son válidas, en el primer caso se usa el valor por defecto de y, en el segundo el valor por defecto de x, en el tercero se invirtió el orden (algo no recomendable pero posible) la y recibe 2 y la x 3. En el cuarto caso no se pasan parámetros y la rutina ejecuta con x e y usando sus valores por defecto.

miércoles 16 de junio de 2010

Eiffel: forma iterativa cómo expresión lógica

En el artículo anterior vimos la nueva sintaxis para los ciclos llamada forma de iteración. Esta forma más compacta de expresar el ciclo (loop) tiene la ventaja de no evitar efectos laterales mediante la utilización implícita de un cursor nuevo.  Está característica hace a esta forma ideal para usarla como expresión lógica y por ende incorporarla a los contratos.

La forma de lograr expresiones lógicas a partir del ciclo es usando alguna de las dos notaciones alternativas para el cuerpo del ciclo en lugar de la palabra loop:

  • some expresión_lógica
  • all expresión_logica

Por ejemplo:

across mi_lista as  ic   all  ic.item.count > 3 end

En este caso tenemos un ciclo que recorre la lista y consulta cada elemento para ver si la propiedad count es mayor a 3. En caso de cumplirse para toda la lista el ciclo cómo expresión lógica es verdadero. En el caso de usar some en lugar de all el ciclo será verdadero si al menos un elemento cumple la condición.

La utilización de all o some como cuerpo del ciclo sólo es permitido si no hay parte de inicialización en el mismo (from).

Evidentemente esta nueva facilidad sintáctica soportada por contratos (por ejemplo no es posible modificar una estructura recorrida por la forma iterativa across, para ello debe usarse la forma tradicional loop) brinda muchas facilidades a los desarrolladores Eiffel.