C# generics and C++ templates are very similar but they work
differently. Generic exist to write code that is reusable across different
types.
Let’s imagine we need a stack of integers if we didn’t have
generic types, one solution is to hard code a separate version of a class for
every required type “IntStack” but when we need stack of string have do the
same way “StrStack”. This would cause considerable code duplication.
However this wouldn’t work aAnother solution would be write a stack that is generalizes by
using Object as element type.s well hard coded “IntStack”
& “StrStack” an “ObjectStack” require boxing & down casting that could
not be checked at compile time.
int x = (int)stack.Pop(); // down casting
What we
need is both a general implementation of a stack that works for all element
type, and a way to easily specialize that stack to a specific element type for
increased type safety and reduced boxing and casing.
Generics
provide this by allowing parameterize element type. Stack<T>
has the benefits of both “ObjectStack”
and “IntStack”.
Test this
example for further understanding.
class Part
{
private string
_PartId;
private string
_PartName;
private string
_PartDescription;
private double
_Weight;
public string PartId
{ get { return
_PartId; } }
public Part(string
PartId, string PartName, string PartDescription, double
Weight)
{
_PartId = PartId;
_PartName = PartName;
_PartDescription = PartDescription;
_Weight = Weight;
}
public override string ToString()
{
return string.Format("Part Id: {0}, Part Name:{1}, Part Description:{2},
weight:{3}", _PartId, _PartName, _PartDescription, _Weight);
}
}
//the actual indexer, which accepts the generic type
//note the type must be a class (not a value type)
class Indexer<T>
where T:class
{
struct ItemStruct
{
public string Key;
public T value;
public ItemStruct(string
key, T value)
{
this.Key = key;
this.value = value;
}
}
List<ItemStruct>
_items = new List<ItemStruct>();
// T must be a class so that can return null if not found
public T Find(string
key)
{
foreach (ItemStruct
_ItemStruct in _items)
{
if (_ItemStruct.Key == key)
{
return _ItemStruct.value;
}
}
return null;
}
public void Add(string key, T value)
{
_items.Add(new ItemStruct(key,
value));
}
}
// Programe
to Test it
class Program
{
static void Main(string[] args)
{
Indexer<Part>
indexer = new Indexer<Part>();
Part p1 = new Part("001",
"Mother Board", "Intel Chip set Mother Board", 0.75);
Part p2 = new Part("002",
"Processor", "Intel Core i5", 0.2);
indexer.Add(p1.PartId, p1);
indexer.Add(p2.PartId, p2);
Part p = indexer.Find("002");
Console.WriteLine(p.ToString());
Console.ReadKey();
}
}