Uncategorized

Generics, una razón para tanto código.

Mucho se ha hablado sobre el uso de GENERICS, o mejor dicho, poco se ha hablado.

Digo poco, porque por que lo general, cuando se hacen introducciones al FrameWork.net 2.0, se suele decir: "… y con la introducción de generics, se ve una mejora significativa, además, nuevos controles…"

En términos generales, es lo máximo que encontramos, por lo que no nos queda mas que recurrir a libros, artículos y otros, de forma
desesperada para saber que es eso que el que nos habla nos los da por asimilado.

Este caso me paso cuando comencé el año pasado a hacer el desarrollador 5 estrellas de Microsoft, donde por todos lados se hablaba de esta innovación, pero no se explicaba que era específicamente.

De cualquier manera, hoy no tengo la intención de explicar con puntos y comas que es generics. Esta información la pueden obtener fácilmente de http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/csharp_generics.asp, o de http://msdn2.microsoft.com/en-us/library/512aeb7t.aspx

En todo caso, quiero hacer énfasis en los innumerables comentarios relacionados a que, usar generics le facilita, por decirlo de una manera, las cosas al "motor" de .Net, y hace que las cosas funcionen un poco más rápidas y optimas.

Para entender el concepto, planteemos el siguiente código:

class Program
{
static int MyInt = 20;

static void Main(string[] args)
{

List<int> MyList = new List<int>();

MyList.Add(10);
MyList.Add(MyInt);

ArrayList MyArrayList = new ArrayList();
MyArrayList.Add(10);
MyArrayList.Add(MyInt);

Console.ReadLine();
}

Esta aplicacion de consola en C#, muy simple, crea dos listas, la primera usando la lista que implementa generics, y la segunda un simple ArrayList.

En ambos casos, y a simple vista, vemos que se le asignan dos elementos, a cada lista, del tipo entero.
Entonces, ¿Dónde esta la diferencia? Para ver la diferencia es necesario compilar nuestro codigo y ver el resultado del mismo.

Veamos entonces el resultado IL de este codigo:

IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.s 10
IL_000a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_000f: nop
IL_0010: ldloc.0
IL_0011: ldsfld int32 GenericsTest.Program::MyInt
IL_0016: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_001b: nop
IL_001c: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
IL_0021: stloc.1
IL_0022: ldloc.1
IL_0023: ldc.i4.s 10
IL_0025: box [mscorlib]System.Int32
IL_002a: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
IL_002f: pop
IL_0030: ldloc.1
IL_0031: ldsfld int32 GenericsTest.Program::MyInt
IL_0036: box [mscorlib]System.Int32
IL_003b: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
IL_0040: pop
IL_0041: call string [mscorlib]System.Console::ReadLine()
IL_0046: pop
IL_0047: ret

Aunque parezca confuso, con un poco de dolor de cabeza, este código puede ser entendible.

Lo importante es recalcar dos lineas, la primera:

IL_0008: ldc.i4.s 10
IL_000a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)

Y la segunda:

IL_0023: ldc.i4.s 10
IL_0025: box [mscorlib]System.Int32
IL_002a: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)

Estas líneas corresponden a la asignación del valor 10 de tipo entero a cada una de las listas. El primero, a la lista generica, y el segundo, al arraylist con el mismo valor.

La diferencia esta, entre otras cosas, en la línea IL_0025: BOX, esto, aunque parezca una pequeñez, es lo que puede hacer que nuestra aplicación "sufra" en rendimiento. Esta llamada hace que el valor de 10 tenga que pasar por el proceso llamado boxing/unboxing. Este proceso, en pocas palabras, se produce al tratar de convertir un value type (variables del tipo enteros, flotantes, etc.) a object type, para
luego poder asignarlo de forma "generica", y valga la contradicción, al arraylist.

Hacer esta conversión requiere de gasto de memoria, procesador entre otros, a diferencia de las líneas creadas con el uso de generics que,
al identificar con anticipación el tipo de datos que esta lista soportara, el IL no necesita hacer juegos de memoria para poder almacenar nuestros valores.

En definitiva, si sabemos que tipos de valores (u objetos) manipularemos en este tipo de objetos (Listas, Clases genericas, etc.), siempre será recomendable el uso de generics.

Standard

2 thoughts on “Generics, una razón para tanto código.

  1. Junior says:

    Muyyyyyyyyyyyyyyyy wenoo gracias , xD! no habia entendido mucho de para que servia , pero si lo explicas asi esta mas claro k el agua , soy de peru nose si me podrias agregar ang_7jd@hotmail.com xD! gracias, Saludos muy bueno.

Leave a reply to Matias Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.