You are on page 1of 31

Generic Classes

Lecture No-21
Date-20/04/2011
Overview
• Generic classes enables us to create classes and
methods that are independent of contained
types. Instead of writing a number of methods or
classes with the same functionality for different
types, you can create just one method or class.
• For example, the mechanism that supports a
queue is the same whether the queue is storing
items of type int, string, object, or a user-defined
class. So, you might have created several
different versions of the same algorithm to
handle different types of data.
• Through the use of generics, you can define a
solution once, independently of any specific
type of data, and then apply that solution to a
wide variety of data types without any
additional effort.
• Generics are not limited to classes. We can
use generic for the creation of structures,
interfaces, methods, and delegates
What Are Generics?
• The term generics means parameterized types.
• Parameterized types are important because they
enable you to create classes, structures,
interfaces, methods, and delegates in which the
type of data upon which they operate is
specified as a parameter.
• For e.g. using generic we can create a class that
automatically works with different types of data.
A class, structure, interface, method, or delegate
that operates on a parameterized type is called
Generic.
The General Form of a Generic Class

• Here is the syntax for declaring a generic


class:
class class-name<type-param-list> { // ...}
• Here is the syntax for declaring a reference to
a generics class:
class-name<type-arg-list> var-name =
new class-name<type-arg-list>(cons-arg-
list);
What it helps in?
• Performance : Generic classes helps in
increasing performance of the application. As
in c# conversion of value types into reference
types need boxing and reference type into
value types need Unboxing. For e.g.
var list = new ArrayList();
list.Add(44); // boxing — automatically
convert a value type to a reference type
Note:ArrayList is a predefined class in C#.
Contd..
int i1 = (int)list[0]; // unboxing — convert a
reference type to a value type
foreach (int i2 in list)
{
Console.WriteLine(i2); // unboxing
}
Boxing and unboxing are easy to use but have
a big performance impact, especially when
iterating through many items.
Contd..
Instead of using Boxing/Unboxing, List < T > class
from the namespace System.Collections.Generic
allows you to define the type when it is used.e.g.
var list = new List < int > ();
list.Add(44); // no boxing — value types are
stored in the List < int >
int i1 = list[0]; // no unboxing, no cast needed
foreach (int i2 in list)
{
Console.WriteLine(i2);
}
• Type safety : Another feature of generics is
type safety. As with the ArrayList class, if
objects are used, any type can be added to this
collection. This example shows adding an
integer, a string, and an object of type MyClass
to the collection of type ArrayList:
var list = new ArrayList();
list.Add(44);
list.Add("mystring");
list.Add(new MyClass());
This will give run-time errors while used in
foreach statement to access elements. Contd..
• foreach (int i in list)
{
Console.WriteLine(i);
}
Complier will accept this code and give run
time error i.e.InvalidCastException while
handling variables except integers.
• With generic List<int>, only integer types can
be added to the collection. The compiler
doesn’t compile this code because the Add()
method has invalid arguments
• var list = new List<int>();
list.Add(44);
list.Add("mystring"); // compile time error
list.Add(new MyClass()); // compile time error
• Binary Code Reuse :Generics allow better
binary code reuse. A generic class can be
defined once and can be used with many
different types.
• For e.g.
Contd..
• var list = new List<int>();
list.Add(44);
var stringList = new List<string>();
stringList.Add("mystring");
var myClassList = new List<MyClass>();
myClassList.Add(new MyClass());
Creating Generic Class
• class Gen<T>
{
T ob; // declare a variable of type T
public Gen(T o)
{
ob = o;
}
public T GetOb()
{
return ob;
} Contd..
public void ShowType()
{
Console.WriteLine("Type of T is " + typeof(T));
}
}
class GenericsDemo
{
static void Main()
{
// Create a Gen reference for int.
Gen<int> iOb; Contd..
// Create a Gen<int> object and assign its reference to
iOb.
iOb = new Gen<int>(102);
iOb.ShowType();
int v = iOb.GetOb();
Console.WriteLine("value: " + v);
Gen<string> strOb = new Gen<string>("Generics add
power.");
strOb.ShowType();
string str = strOb.GetOb();
Console.WriteLine("value: " + str);
}
}
The output
Type of T is System.Int32
value: 102
Type of T is System.String
value: Generics add power.
Generic Class using 2 Parameters
class TwoGen<T, V>
{
T ob1;
V ob2;
public TwoGen(T o1, V o2)
{
ob1 = o1;
ob2 = o2;
} Contd..
public void showTypes()
{
Console.WriteLine("Type of T is " + typeof(T));
Console.WriteLine("Type of V is " + typeof(V));
}
public T getob1()
{
return ob1;
}
public V GetObj2()
{
return ob2;
}
} Contd..
class SimpGen
{
static void Main()
{
TwoGen<int, string> tgObj =
new TwoGen<int, string>(119, "Alpha
Beta Gamma");
tgObj.showTypes();
int v = tgObj.getob1();
Console.WriteLine("value: " + v); Contd..
string str = tgObj.GetObj2();
Console.WriteLine("value: " + str);
}
}
• The output :
Type of T is System.Int32
Type of V is System.String
value: 119
value: Alpha Beta Gamma
Generic Methods
• In addition to defining generic classes, it is
also possible to define generic methods. With
a generic. Generic methods can be defined
within non – generic classes.
• The syntax is:
returntype nameofmethod<type>(para)
{
}
Such as: Contd..
• void Swap<T>(ref T x, ref T y)
{
T temp;
temp = x;
x = y;
y = temp;
}
• A generic method can be invoked by assigning the
generic type with the method call:
int i = 4;
int j = 5;
Swap<int>(ref i, ref j);
Generic Interfaces
• Using generics, you can define interfaces that
define methods with generic parameters.
• Methods are defined like any other non-
generic method but following with<type>.
• public interface I1< T>
• {
• void Hello(T t1);
• } Contd..
• public class Greet : I1<Greet>
• {
• int x;
• public Greet()
• {
• x = 0;
• }
• public void Hello(Greet g)
• {
• Console.WriteLine(g.x);
• Console.WriteLine("Good Morning to all!");
• }
• }
• class main2
• {
• static void Main()
• {
• Greet g1 = new Greet();
• Greet g2=new Greet ();
• g1.Hello(g2);
• Console.ReadKey();
• }
• }
The output:
• 0
• Good Morning to all!
Generic Structure
• Similar to classes, structs can be generic as
well. They are very similar to generic classes
with the exception of inheritance features.
• The syntax to define generic struct is similar
to classes.
• struct structname<type>
{
……
} Contd.,
• struct Swap<T>
• {
• public void swapping(ref T a,ref T b)
• {
• T temp = a;
• a = b;
• b = temp;
• }
• }
Contd..
• class Class5
• {
• public static void Main()
• {
• Swap<int> ob1 = new Swap<int>();
• int a = 3, b = 5;
• double d1 = 2.3, d2 = 3.4;
• ob1.swapping(ref a,ref b);
• Console.WriteLine("a=" + a + "b=" + b);
Contd..
• Swap<double> ob2 = new Swap<double>();
• ob2.swapping(ref d1,ref d2);
• Console.WriteLine("d1=" + d1 + "d2=" +
d2);
• Console.ReadKey();
• }
• }
• Default Values: Generic Classes can’t be NULL so we can
use default values. With the default keyword, null is
assigned to reference types and 0 is assigned to value
types:
public T Get()
{
T temp = default(T);
}
• The default keyword has multiple meanings depending
on the context where it is used. The switch statement uses
a default for defining the default case, and with generics
default is used to initialize generic types either to null or
0 depending on if it is a reference or value type. Contd..

You might also like