Lazy initialization en .NET 4

by Misael Monterroca 26. October 2009 06:27

La inicialización del tipo Lazy (la traducción seria perezosa pero se refiere al hecho de crear un objeto hasta el momento de realmente utilizarlo aún y cuando el objeto sea instanciado en líneas anteriores) permite optimizar la manera en que creamos nuestros objetos.  En .Net. C# 4.0 se introduce la clase Lazy<T> que permite inicializar los objetos hasta que realmente los vayamos a utilizar, veamos el siguiente ejemplo:

class Program
{
    static void Main(string[] args)
    {
        Lazy<Prueba> f = new Lazy<Prueba>( );
        Console.WriteLine("Prueba es definida");
        if (!f.IsValueCreated) Console.WriteLine("Prueba aún no ha sido inicializada");
        Console.WriteLine("Prueba::ID=" + (f.Value as Prueba).ID);
        
        if (f.IsValueCreated) Console.WriteLine("Prueba ahora si está inicializada");
        Console.Read();
    }
} 

public class Prueba
{
    public int ID { get; set; }
    
    public Prueba()
    {
        Console.WriteLine("Prueba:: El constructor es llamado");
        ID = 1;
    }
}

La ejecución obtendría el siguiente resultado:

Prueba es definida
Prueba aún no ha sido inicializada
Prueba:: El constructor es llamado
Prueba::ID=1
Prueba ahora si está inicializada

Como podemos ver el objeto Prueba se crea sólo cuando f.Value es accesado.

Tags: ,

C# | C# 4.0

Named and Optional Parameters

by Misael Monterroca 29. September 2009 06:15

C # 4.0 ha añadido dos nuevas características en relación con los parámetros que deberían contribuir a mejorar la productividad del desarrollador.  Parametros Opcionales y Parametros por nombre permitirá  nuevas maneras de resolver viejos problemas.

Parámetros opcionales

En el pasado, cuando queríamos crear métodos con un número variable de parámetros debiamos utilizar métodos sobrecargados. La sobrecarga es el proceso de creación de métodos con el mismo nombre pero de diferentes parámetros. Por ejemplo, digamos que tenemos un método denominado GetRandomNumber que cuenta con tres firmas de métodos diferentes:

 

01    static void Main(string[] args)
02    private static Random random = new Random();      
03     
04    public static int GetRandomNumber(int max)
05    {
06        return random.Next(max);
07    }
08     
09    public static int GetRandomNumber(int min, int max)
10    {
11        return random.Next(min, max);
12    }
13     
14    public static int GetRandomNumber()
15    {
16        return random.Next();
17    }

Con C # 4, ahora podemos consolidar estas en un método con parámetros opcionales. Los parámetros opcionales le permiten declarar e inicializar una variable dentro de la firma del método. Cualquier parámetro que tiene un valor por defecto asignado a ella puede ser excluido al invocar el método. Por lo tanto podemos consolidar nuestro código anterior:

01    private static Random random = new Random();
02     
03    public static int GetRandomNumber(int min = -1, int max = -1)
04    {           
05        if (min == -1 && max != -1)
06            return random.Next(max);
07        else if (min != -1 && max != -1)
08            return random.Next(min, max);
09        else
10            return random.Next();
11    }

 

El escenario clásico para el uso de parámetros opcionales surge cuando están interactuando con interfaces COM como la Automatización de Microsoft Office API. Si usted ha trabajado con las APIs de Office antes, entonces estoy seguro de que usted está familiarizado con el Type.Missing. Antes de C # 4.0, tendríamos que utilizar el siguiente código para dar formato a un rango de celdas con Excel:

1    var excel = new Microsoft.Office.Interop.Excel.Application();
2    excel.Workbooks.Add();
3    excel.Visible = true;
4     
5    var format = Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic1;
6     
7    excel.get_Range("B10", "B40").AutoFormat(format,
8       //y !6! Type.Missing
9       Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

Este código parece un desperdicio debido al hecho de que tenemos que llenar en seis de los siete parámetros con Type.Missing. En C # 4.0, la llamada al método  AutoFormat se simplifica. Básicamente, se pueden prevenir todos los parámetros repetitivos como Type.Missing y solo especificar el primer parámetro, como en siguiente ejemplo:

excel.get_Range("B10", "B40").AutoFormat( format );

Parámetros con nombre

Named Parameters es la otra nueva característica en C # 4.0. Los parámetros con nombre son muy útiles en situaciones en las que es fácil olvidar el orden en el que los parámetros están especificados. Volviendo a mi primer ejemplo que tenía un generador de números aleatorios que tiene un valor mínimo y un valor máximo. Si por alguna razón se invirtieran el valor de los parámetros obviamente el resultado seria equivocados. Sin embargo, con Named Parameters podemos seleccionar los parámetros especificando el nombre del parámetro y el valor. Aquí está un ejemplo:

 

Console.WriteLine( GetRandomNumber( max : 100, min : 1 ) );

Tags: ,

C# | C# 4.0

Clases Parciales

by Misael Monterroca 18. August 2009 13:57

En general, las clases se definen en un mismo archivo fuente (Clase1.cs, Clase2.cs etc) . A veces, esto puede conducir a dificultades, un ejemplo es una clase que está parcialmente generado por un generador de código, y parcialmente modificada y mantenida por el desarrollador.

Este es un escenario muy común, WinForms y diseñadores de formularios Web Forms tiene este problema, haciendo que estas clases sean vulnerables a la modificación accidental de código fuente que no está destinado a ser modificada por el desarrollador. Para resolver este problema, el código generado por el diseñador WinForm está escondido en una región y generalmente nunca es modificada por ningún desarrollador.

C # presenta una característica que puede resolver estos problemas: las clases parciales. Estas son clases que se definen en más de un archivo de origen. De esta manera, parte de una clase parcial podría ser gestionada por el generador de código y una segunda parte de la clase podría ser gestionada por el desarrollador. Cuando el código se compila, el compilador de C # realiza lo que se puede describir como una  fusión que combina todas las partes en una clase.

He aquí un ejemplo de código. En primer lugar, podría haber una parte de una clase definida en un archivo de origen:

 

public partial class Class1
{
   public string Test()
   {
      return "Prueba";
   }
}

Entonces, podría haber una segunda fuente de archivos con la siguiente definición de clase:

 

public partial class Class1
{
   public string SomethingElse()
   {
      return "Alguna otra funcionalidad más";
   }
}

La parte importante es la definición de la clase es la palabra clave partial, lo que hace que el nombre duplicado de la clase sea válido, además instruye al compilador a fusionar las dos partes.

Por supuesto, esta fusión puede ser útil para un número de diferentes aplicaciones prácticas, los generadores de código es uno de ellos. Además, las clases parciales se pueden utilizar crear grandes clases en pedacitos más pequeños, que puede ser muy útil en escenarios de desarrollo ya que puede ser una característica útil cuando se trata de agregar funcionalidad a una clase de depuración ya que una de las partes podría tener toda la funcionalidad de depuración, y en otra, el código esperado, una vez que el producto este listo, la clase que contenga el código de depuración podría ser removido sin afectar el código esperado.

Tags:

C# | c

Métodos Anónimo

by Misael Monterroca 3. August 2009 13:42

Los delegados son objetos que encapsulan las referencias a las funciones. Uno de los usos comunes de la mayoría de los delegados es la implementación de controladores para eventos.

Para ver esto en acción, cree un nuevo proyecto Windows Forms (WinForms) y arraste un botón al formulario, a continuación, haga doble clic en el botón para crear el código que controlará el evento click,  el diseñador de formularios Windows Forms creara dos piezas separadas de código.

 

private void button1 (object sender, System.EventArgs e)
(
MessageBox.Show ("Prueba");
)

Además, y por lo general oculta en la región de la forma de código generado por el diseñador, el código está conectado al evento de clic del botón:

this. Button1.Click + = System.EventHandler (this. Button1);

Tenga en cuenta que el método controlador de eventos tiene que ser conforme a una firma determinada (dos parámetros del tipo de object y System.EventArgs en este caso). Esta firma se define en el delegado System.EventHandler.

La gran pregunta es: ¿Qué ganamos con la creación de este método independiente que está ligado al evento de clic a través del delegado EventHandler? Bueno, no mucho, porque no hay una verdadera necesidad para llamar al método de otro modo. Pero todo esto es necesario para hacer el trabajo de gestión de eventos.

Métodos Anónimo simplifica esto un poco. En lugar de crear instancias de un delegado y la creación de un método, el código para el método de control podrá ser creado dentro de la misma línea de código.

 

this.button1.Click += 
delegate(object sender, EventArgs e)
  {    MessageBox.Show("Prueba");   };

Como puede ver, lo que se asigna al evento Click no es un puntero a un método. Tenga en cuenta que tiene que haber un punto y coma al final, porque todo esto es realmente sólo una línea de código.

Uno de los usos geniales de esta técnica es la capacidad de pasar código como parámetro. Imagine un escenario en el que se utiliza un delegado como un call-back, un patrón que se utiliza habitualmente en una serie de escenarios, como la programación asincrónica, o cada vez que un proceso informe sobre sus avances. He aquí un ejemplo que ilustra esto:

 

public delegate void 
  Feedback(string Text);

public void Execute(Feedback d1)
{
  d1("Iniciando...");
  // Más código
  d1("Inicializando aplicación...");
  // Mucho Más código
  d1("Inicialización terminada.");
}

Uno puede crear instancias de un delegado que encapsule un método con un parámetro de cadena y páselo al método Execute para recibir información sobre el progreso del método. Alternativamente, usted puede llamar al método y pasar el código de retroalimentación como un parámetro:

 

Execute(
  delegate(string s)
  {MessageBox.Show(s);} );

Así que todo dentro del paréntesis del método  Execute () es el método anónimo y, por supuesto, se puede pasar en tantas líneas de código que desee. un punto importante a recalcar es que los métodos anónimos pueden ver realmente las variables locales definidas en el método de llamada. Así que esto funcionaria adecuadamente:

 

string s2 = "Prueba";
Execute(
  delegate(string s)
  {MessageBox.Show(s+s2);} )

Tags:

C#

MVP