Si queremos definir un tipo, llamado stack (pila), no generico tenemos algo como esto:
class Stack {
private object[] store;
private int size;
public Stack()
store=new object[10]; size=0;
}
Ahora si lo quieren genérico, aqui está lo interesante del asunto:
class Stack
private T[] store;
private int size;
public Stack()
store=new T[10]; size=0;
}
Fijense que sería como una especie de plantilla, para la cual definiremos cualquier tipo de dato, consiguiendo una clase stack de tipos genéricos. En el caso no genérico tenemos por ejemplo un arreglo store como tipo object, lo que supone recibir cualquier tipo de datos, pero incurriendo obviamente en la costosa operación de boxing y unboxing.
Por el contrario, con nuestro modelo genérico el arreglo store, está habilitado para ser del tipo que le definamos sin incurrir en operaciones de boxing y unboxing.
Hasta el momento el ejemplo nos muestra que podemos definir tanto Clases como sus miembros de tipo genérico.
Pero ahora veamos la implementación de los métodos de ingreso y sacada de elementos de la pila en el modo no genérico:
public void Push(object x) {
if (size>=store.Size) {
object[] tmp = new object[size*2];
Array.Copy(store,tmp,size);
store = tmp;
}
store[size++] = x;
}
public object Pop() {
return store[--size];
}
Es de observar el uso de object como forma de recibir cualquier tipo de dato, pero si le pasamos tipos primitivos, incurrimos en la no bienvenida operación de box, por ejemplo, compilemos lo anterior y analicemos un poco el IL generado.
En la ventana generada gracias al ILDASM.EXE en la línea IL_000a: box, se aprecia una clara llamada a una operación de box. Ahora imaginense esto ocurriendo por cada elemento que entre a la pila de tipo primitivo, en este caso un entero, que deberá ser casteado a Object.
Ahora observermos la versión genérica mirada a través de la lupa del ILDASM:
public void Push(T x)
{
if (size>=store.Length)
{
T[] tmp = new T[size*2];
Array.Copy(store,tmp,size);
store = tmp;
}
store[size++] = x;
}
public T Pop()
{
return store[--size];
}
Alguien me puede ayudar a buscar la operación de Box que no la veo. Si señores, una ventaja de Generics vista en puro C# convertido a IL.
Como se puede observar, igualmente nuestra clase genérica puede también tener Métodos genéricos, el caso de Pop() y métodos no genéricos que reciben tipos genéricos el caso de Push().
Este ejmplo lo tome del artículo http://research.microsoft.com/projects/clrgen/generics.pdf
y quise comprobar a través del ILDASM, para ver de cerca una de las ventajas claras de Generics Types.
No comments:
Post a Comment