Introduction:

Question to Mr. C# Corner:
Hello. Mr. C# Corner. I'm Developer, I want to know why you advice me to use Generic instead of Casting Objects and what is the meaning of a Generic?
Answer: One of the important issues in the code development is the [Coding Quality], because your Coding Quality seperates you from other developers. So let us see what are the basics of the coding quality:
  • Application Performance.
  • Reducing of Casting Object-based data structures.
  • Reuse data processing Algorithms (code).

Question to Mr. C# Corner! You say "reduce Casting" of Objects. So what about casting Objects when using Collections (Boxing in general)?
Answer: Ooh...I would like to see the following example which explains the advantage of using generics and how it is more efficient than using non-generic code and how does this matter in coding quality.
Getting Started
What is a Generic: Generics are a new feature in version 2.0 of the C# language and the common language runtime (CLR).
  • Generics introduce you to the .NET Framework the concept of type parameters, which makes it possible to design classes, and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code.
  • Generics allow you to define type-safe data structures, without committing to actual data types.

Let us see Simple Example about Using and benefits of Generics:
Let us see the difference between a non-generic class and a generic class with your eyes only:


Generic.jpg

In Figure 1:
Tip!! :
ArrayList is a highly convenient collection class that can be used without modification to store any reference or value type.

Disadvantage of Casting (Boxing)
So if you think about generalizing you collection class, what you will do in C# 1.1?

You could avoid the dangers of generalized code in the .NET Framework base class library collection classes by writing your own type specific collections. Of course, since such a class is not reusable for more than one data type, you lose the benefits of generalization, and you have to rewrite the class for each type that will be stored.

In Figure 2:
Let us see what is happen in C# 2.0 to solve these problems:
What ArrayList and other similar classes really need is:

static void GenericTest()

{

// The .NET Framework 2.0 way to create a list

List<int> list1 = new List<int>();

// No boxing, no casting:

list1.Add(3);

// Compile-time error:

// list1.Add("It is raining in Redmond.");

}

For example using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations.

// Declare the generic class

public class GenericList<T>

{

void Add(T input)

{

}

}

class TestGenericList

{

private class ExampleClass

{

}

static void Main()

{

// Declare a list of type int

GenericList<int> list1 = new GenericList<int>();

// Declare a list of type string

GenericList<string> list2 = new GenericList<string>();

// Declare a list of type ExampleClass

GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();

}

}
Get Started:
The boxing and Un-Boxing:
What is boxing and Un-Boxing in C#?
Boxing a value type packages it inside an instance of the Object reference type.
Boxing Example:
(a) most used Boxing:

int i = 10;

object Obj = i;

(b) It also possible to perform the boxing explicitly as in the following:

int i = 10;

// Casting the value type [ int ] to Object Reference type boxing

object Obj = (object)i;

How Boxing performed?


Boxing.jpg


1- Declare a value-type variable [i] as int

int i = 10;
2- then applies the boxing operation on the variable [i]

object Obj = i;
3- The result of this statement is creating an object reference Obj on the stack.
4- This Object references a value of the type int, on the heap. This value is a copy of the value-type value assigned to the variable [i] which equal 10.
What are the Benefits of this concept?
To allow the value type to be stored on the garbage collected heap.
Un-Boxing Example:

Obj = 10;

// Unboxing extracts the value type from the object Ref Type

i = (int)Obj;

! Disadvantage of Boxing
Boxing and un-Boxing are expensive processes because of the following:

  1. when a value type is boxed, an entirely new instance object must be allocated and constructed.
  2. The cast required for un-boxing is also expensive computationally.

Generic is better than using Object based Solution to reducing Object casting Let us see how?
With using Boxing:

readonly int m_Size;

int m_StackPointer = 0;

object[] m_Items;

public void Push(object item)

{

if (m_StackPointer >= m_Size)

throw new StackOverflowException();

m_Items[m_StackPointer] = item;

m_StackPointer++;

}

With using Generic:

readonly int m_Size;

int m_StackPointer = 0;

T[] m_Items;

public void Push(T item)

{

if (m_StackPointer >= m_Size)

throw new StackOverflowException();

m_Items[m_StackPointer] = item;

m_StackPointer++;

}