You are currently browsing the tag archive for the 'Generics' tag.
En este post voy a escribir sobre métodos genéricos. La idea es presentar un método que acepte dos parámetros de tipo genérico.
Para quien no maneje el concepto de Generics recomiendo antes leer este post.
Vamos a usar un proyecto de tipo Consola con Visual Studio .NET, y la misma clase Libro que usé en el post anterior.
Primero, referenciamos lo siguiente:
C#
using System;
using System.Collections.Generic;
VB.NET
Imports System
Imports System.Collections.Generic
Ahora si, la clase Libro:
C#
public class Libro
{
public string sTitulo, sAutor;
public Libro(string Titulo, string Autor)
{
sTitulo = Titulo;
sAutor = Autor;
}
public override string ToString()
{
return string.Format(“{0} escribió {1}.”, sAutor, sTitulo);
}
}
VB.NET
Public Class Libro
Dim sTitulo, sAutor As String
Public Sub New(ByVal Titulo As String, ByVal Autor As String)
MyBase.New()
sTitulo = Titulo
sAutor = Autor
End Sub
Public Overrides Function ToString() As String
Return String.Format(“{0} escribió {1}.”, sAutor, sTitulo)
End Function
End Class
En el módulo principal codificamos nuestro método MostrarPorConsola que podrá recibir dos parámetros de cualquier tipo:
C#
static void MostrarPorConsola<T>(ref T a, ref T b)
{
Console.WriteLine(“Primer argumento del método MostrarPorConsola(), {0}, de tipo {1}.”, a, typeof(T));
Console.WriteLine(“Segundo argumento del método MostrarPorConsola(), {0}, de tipo {1}.”, b, typeof(T));
}
VB:NET
Private Sub MostrarPorConsola(Of T)(ByRef a As T, ByRef b As T)
Console.WriteLine(“Primer argumento del método MostrarPorConsola(), {0}, de tipo {1}.”, a, GetType(T))
Console.WriteLine(“Segundo argumento del método MostrarPorConsola(), {0}, de tipo {1}.”, b, GetType(T))
End Sub
El método imprime una línea con el primer argumento y otra más con el segundo, sin interesar de que tipo son.
En la rutina principal consumimos al método genérico, primero declaro dos enteros, les asigno un valor y se los paso como parámetros al método MostrarPorConsola, luego declaro dos objetos de tipo Libro, los hidrato y se los paso como parámetros al mismo método.
Parece mentira… pero funciona
A partir de la versión 2.0 del Framework .NET contamos con el namespace Generics que define una cantidad de clases e interfaces que permiten administrar sub ítems en una variedad de contenedores. En este post me voy a dedicar al contenedor List<T> o List(Of T) según sea C# o VB.NET
Veamos un ejemplo de colección sin Generics. Con Visual Studio .NET, abrimos un nuevo proyecto de Consola, si queremos manipular un conjunto de objetos, por ejemplo Libros, en primer lugar tenemos que referenciar lo siguiente:
C#
using System;
using System.Collections;
VB.NET
Imports System
Imports System.Collections
y definir la clase Libro:
C#
public class Libro
{
public string sTitulo, sAutor;
public Libro(string Titulo, string Autor)
{
sTitulo = Titulo;
sAutor = Autor;
}
public override string ToString()
{
return string.Format(“{0} escribió {1}.”, sAutor, sTitulo);
}
}
VB.NET
Public Class Libro
Dim sTitulo, sAutor As String
Public Sub New(ByVal Titulo As String, ByVal Autor As String)
MyBase.New()
sTitulo = Titulo
sAutor = Autor
End Sub
Public Overrides Function ToString() As String
Return String.Format(“{0} escribió {1}.”, sAutor, sTitulo)
End Function
End Class
Además, necesitamos programar otra clase, por ejemplo BibliotecaCollection que implemente la intefaz IEnumerable. En nuestro caso le agregaremos un método AgregarLibro que recibe un parámetro de tipo Libro y lo agrega a un ArrayList que la clase encapsula.
El tipo ArrayList en el namespace Collection, es el equivalente al tipo List<T> o List(Of T) del namespace Generics
C#
public class BibliotecaCollection : IEnumerable
{
private ArrayList arBiblioteca = new ArrayList();
public BibliotecaCollection() { }
public void AgregarLibro(Libro pLibro)
{
arBiblioteca.Add(pLibro);
}
IEnumerator IEnumerable.GetEnumerator()
{
return arBiblioteca.GetEnumerator();
}
}
VB.NET
Public Class BibliotecaCollection
Implements IEnumerable
Private arBiblioteca As ArrayList = New ArrayList
Public Sub New()
MyBase.New()
End Sub
Public Sub AgregarLibro(ByVal pLibro As Libro)
arBiblioteca.Add(pLibro)
End Sub
Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return arBiblioteca.GetEnumerator
End Function
End Class
Cualquier otro tipo de función que queramos que soporte la clase, debemos codificarla. Para este ejemplo sólo vamos a dejar definida la función AgregarLibro.
Ahora si podemos hacer uso de nuestra biblioteca en una aplicación de consola:
C#
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“Collections\n”);
BibliotecaCollection miBiblioteca = new BibliotecaCollection();
miBiblioteca.AgregarLibro(new Libro(“Trópico de Cáncer”, “Henry Miller”));
miBiblioteca.AgregarLibro(new Libro(“Yonqui”, “William Burrougs”));
miBiblioteca.AgregarLibro(new Libro(“Esperando a Godot”, “Samuel Beckett”));
miBiblioteca.AgregarLibro(new Libro(“La senda del perdedor”, “Charles Bukowski”));
miBiblioteca.AgregarLibro(new Libro(“En el camino”, “Jacques Kerouac”));
foreach (Libro pLibro in miBiblioteca)
Console.WriteLine(pLibro);
Console.ReadLine();
}
}
VB.NET
Module Module1
Sub Main()
Console.WriteLine(“Collections”)
Dim miBiblioteca As BibliotecaCollection = New BibliotecaCollection
miBiblioteca.AgregarLibro(New Libro(“Trópico de Cáncer”, “Henry Miller”))
miBiblioteca.AgregarLibro(New Libro(“Yonqui”, “William Burrougs”))
miBiblioteca.AgregarLibro(New Libro(“Esperando a Godot”, “Samuel Beckett”))
miBiblioteca.AgregarLibro(New Libro(“La senda del perdedor”, “Charles Bukowski”))
miBiblioteca.AgregarLibro(New Libro(“En el camino”, “Jacques Kerouac”))
For Each pLibro As Libro In miBiblioteca
Console.WriteLine(pLibro)
Next
Console.ReadLine()
End Sub
End Module
Ahora, con Generics, no necesitamos de la clase BibliotecaCollection, ni implementar la interfaz IEnumerable, ni el método adicional AgregarLibro.
Sólo necesitamos declarar una lista genérica de Libros de la siguiente forma:
C#
List<Libro> miBiblioteca = new List<Libro>();
VB.NET
Dim miBiblioteca As List(Of Libro) = New List(Of Libro)
Tenemos que modificar levemente las referencias a:
C#
using System;
using System.Collections.Generic;
VB.NET
Imports System
Imports System.Collections.Generic
Y con la misma declaración de la clase Libro que tenemos más arriba usamos nuestra lista genérica de Libros de esta forma:
C#
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“Generics\n”);
List<Libro> miBiblioteca = new List<Libro>();
miBiblioteca.Add(new Libro(“Trópico de Cáncer”, “Henry Miller”));
miBiblioteca.Add(new Libro(“Yonqui”, “William Burrougs”));
miBiblioteca.Add(new Libro(“Esperando a Godot”, “Samuel Beckett”));
miBiblioteca.Add(new Libro(“La senda del perdedor”, “Charles Bukowski”));
miBiblioteca.Add(new Libro(“En el camino”, “Jacques Kerouac”));
foreach (Libro pLibro in miBiblioteca)
Console.WriteLine(pLibro);
Console.ReadLine();
}
}
VB.NET
Module Module1
Sub Main()
Console.WriteLine(“Generics”)
Dim miBiblioteca As List(Of Libro) = New List(Of Libro)
miBiblioteca.Add(New Libro(“Trópico de Cáncer”, “Henry Miller”))
miBiblioteca.Add(New Libro(“Yonqui”, “William Burrougs”))
miBiblioteca.Add(New Libro(“Esperando a Godot”, “Samuel Beckett”))
miBiblioteca.Add(New Libro(“La senda del perdedor”, “Charles Bukowski”))
miBiblioteca.Add(New Libro(“En el camino”, “Jacques Kerouac”))
For Each pLibro As Libro In miBiblioteca
Console.WriteLine(pLibro)
Next
Console.ReadLine()
End Sub
End Module
Como vemos en el namespace Generics se resuelve todo lo que antes debíamos codificar en una clase adicional, en este ejemplo BibliotecaCollection.
Los otros contenedores del namespace que no cubro en este post son:
Collection<T>, la base de una colección genérica,
Comparer<T>, Comparación de igualdad entre dos objetos genéricos,
Dictionary<K, V>, colección genérica de pares nombre/valor,
Queue<T>, implementación genérica de lista FIFO (first-in, first-out),
SortedDictionary<K, V>, implementación genérica de un conjunto ordenado de pares nombre/valor,
Stack<T>, implementación genérica de lista LIFO (last-in, first-out),
LinkedList<T>, implementación genérica de una lista doblemente vinculada,
ReadOnlyCollection<T>, implementación de un conjunto de items genéricos de sólo lectura.
En fin, contamos con una nueva serie de elementos para aprovechar la potencia del Framework.
