By Chandra Hundigam
Introduction
Before we start
tampering around the code, lets understand why we need a generic type? Well in
most of application development we come across lots of situation where we need a
type which can hold both value types and reference type. In this situation we
need a generic type which can do both. Before we start working on generic type,
lets understand little about types in .Net as we know there are two fundamental
categories of types
1]value
types
(example : structures,primitive type,enums)
2]reference
types (example : Classes,interface,arrays,strings etc..,)
So when you are
using any one of the above types they are bonded to that particular type. For
example if we declare a structure it bonds to value type and when we declare a
class it bonds to reference type. Despite the fact that declaration syntax is
same for both but semantics are distinct. And
in terms of memory allocation for value is on stack and where as for reference
type is on run-time heap.
Assignment to a variable of value types creates
a copy of the value.
For example:
//vtyp.cs
using System;
public class valTyp
{
public static void Main()
{
Int32 I=10,J=0;
J=I;
// this will create a copy value I into J
I++;
Console.WriteLine( "I value: {0}, J value {1}",I,J);
}
}
Output:
D:\vstudio>vtype
I value: 11, J value 10
The assignment to
the local variable J does not impact the local variable I because
both local variables are of a value type (the type Integer) and each
local variable of a value type has its own storage.
But Assignment to a
variable of a reference type creates a copy of the reference, not a copy of the
value being referenced let’s see this with an example below.
For example:
//vref.cs
using System;
public class Cclass
{
public int val = 0;
}
public class refTyp
{
public static void Main()
{
Cclass ref1 = new Cclass();
Cclass ref2=ref1;
ref2.val = 555;
Console.WriteLine( "Before increament Ref1 value: {0}, Ref2 value {1}",ref1.val,ref2.val);
ref2.val++;
Console.WriteLine( "After increament Ref1 value: {0}, Ref2 value {1}",ref1.val,ref2.val);
}
}
Output:
D:\vstudio>vref
Before increament Ref1 value: 555, Ref2 value 555
After increament Ref1 value: 556, Ref2 value 556
In contrast with
value type the assignment to reference type variable ref2.val = 555,
affects the object that both ref1 and ref2 reference.
From above we see
that value types and reference types are different. So to create a Generic
type we need something which neither of them. In .net we have the
root type Object (alias System.Object)
is special in that it is neither a reference type nor a value type, and may not
be instantiated. So a variable of type Object
can either contain a value type or a reference type. Yes there is question,
which arises in mind why Object class can
handle both?
The answer is both
reference and value types are derived from the base class Object.
So using the concept Boxing and unboxing we can treat any type
as an object. So what does boxing do, So where its necessary for a value type to
behave like a object boxing is done which wrappers the value type to look like a
reference object (allocated on heap), and the value type’s value is copied
into it. Then this complete wrapper is marked so that CLR knows that it
contains a value type. Similarly the reverse process is called as unboxing.
Let’s see a sample code using Object
class as Generic type:
// objapp.cs
using
System;
public
class Myclass
{
public string
name="Hello from Myclass";
public void
doSomething()
{
Console.WriteLine(name);
}
}
public
class ObjApp{
public
static void CheckType(object o)
{
if
(o is string)
{
Console.WriteLine ("o is
String");
string s = (string)o;
Console.WriteLine (s);
}
else
if (o is Int32[])
{
Console.WriteLine ("o is Int32
array");
Int32[] ins=(Int32[])o;
for(Int32 i=0;i< ins.Length;i++)
Console.WriteLine (ins[i]);
}
else
if (o is Myclass)
{
Console.WriteLine ("o is
Myclass");
Myclass a = (Myclass)o;
a.doSomething();
}
}
public static
void Main(){
//
Create an array of Object references
Object[]
objs = new Object[3];
objs[0]
= "Some String"; // create a new string
objs[1]
= new Int32[]{1, 2, 4}; // create a new Int32 array
objs[2]
= new Myclass(); // create a new
Object instance
for(Int32
ind = 0; ind < 3; ind++)
{
Console.WriteLine("Array index
{0} refers to {1}",ind, objs[ind]);
ObjApp.CheckType(objs[ind]);
}
}
}
Output:
Array
index 0 refers to Some String
o is
String
Some
String
Array
index 1 refers to System.Int32[]
o is
Int32 array
1
2
4
Array
index 2 refers to Myclass
o is
Myclass
Hello
from Myclass
In
the above program if you see Object class
can take any type and in CheckType member
function we are sending the generic type (Object)
and using is operator we are checking the
type which is passed as parameter to the function , Then using Boxing
we can point to the specific type and use for further processing.
Further
reading
- .Net
More information on .Net technologies
About
the Author: Chandra
Hundigam has Master degree is Computer Application, Working on Microsoft
Technologies for past 5 years. Presently working as consultant for a US based
company. His area of interests is Emerging Technologies.