Nell’articolo precedente abbiamo introdotto i generics. In questo nuovo articolo introduciamo le interfacce generiche.
Nulla di particolarmente complesso, è sufficiente definire nel modo tradizionale l’interfaccia, indicando però un parametro generico:
public interface ICounter<T>
{
}
Allo stesso modo è possibile indicare il valore di ritorno che dovrà essere sovrascritto:
public interface ICounter<T>
{
int Count { get; }
T Get(int index);
}
Ovviamente, come per l’utilizzo di interfacce “tipizzate”, è possibile sfruttare l’ereditarietà:
public interface ICounter<T>
{
int Count { get; }
T Get(int index);
}
public interface IPersons<T> : ICounter<T>
{
void Add(T item);
}
Implementare un’interfaccia generica
Le classi che implementano un’interfaccia generica devono sottostare alle specifiche definite all’interno dell’interfaccia stessa.
public interface ICounter<T>
{
int Count { get; }
T Get(int index);
}
public interface IPersons<T> : ICounter<T>
{
void Add(T item);
}
public class People<T> : IPersons<T>
{
...
}
Ovviamente dovranno essere implementati TUTTI i metodi specificati all’interno delle interfacce.
Passare un’interfaccia generica come parametro
Un’interfaccia generica è a tutti gli effetti un’interfaccia: possiamo quindi utilizzarla come parametro di un metodo. Supponiamo, ad esempio, di aver definito un’interfaccia che rappresenta una forma geometrica:
public interface IShapes<T>
{
int Count { get; }
void Add(T item);
T Get(int index);
}
Allo stesso modo definiamo un’interfaccia per un oggetto di tipo “Round” :
public interface IRound
{
string Name { get; }
double Radius { get; set; }
double Diameter { get; }
double Circumference { get; }
double Area { get; }
}
A questo punto procediamo con l’implementazione della classe Circle (che implementa l’oggetto IRound:
public class Circle : IRound
{
...
...
}
A questo punto, da un’ ipotetica di una classe è possibile utilizzare un’interfaccia come parametro di un metodo, nel seguente modo:
public void ShowShapes(IShapes<IRound> shps) { for (int i = 0; i < shps.Count; i++) { IRound rnd = shps.Get(i); Console.WriteLine("================================"); Console.WriteLine("{0} Characteristics", rnd.Name); Console.WriteLine("--------------------------------"); Console.WriteLine("Radius: {0}", rnd.Radius); Console.WriteLine("Diameter: {0}", rnd.Diameter); Console.WriteLine("Circumference: {0}", rnd.Circumference); Console.WriteLine("Area: {0}", rnd.Area); } Console.WriteLine("==============================="); }
Restituire un’interfaccia generica come parametro
E’ possibile restituire un’interfaccia generica da un metodo nel seguente modo:
public IShapes<IRound> GetShapes()
{
...
}
Ovviamente il tipo ritornato deve soddisfare tutte le regole definite all’interno dell’interfaccia.