What are Generics in C# (C Sharp)

Most of you will be using collections to deal with set of elements. Collection that you might frequently use is ArrayList. This article will tell you about the drawbacks of ArrayList and propose an alternative for it. To start with, here is a simple example for ArrayList.

class sampleClass {
public static void Main( ) {
ArrayList stringList = new ArrayList( );
stringList.Add(“sample string1”);
stringList.Add(“sample string2”);
foreach (string item in stringList) {
Console.WriteLine(item);
}
ArrayList integerList = new ArrayList( );
integerList.Add(100);
integerList.Add(200);
foreach (int item in integerList) {
Console.WriteLine(item);
}
}
}

In this example, you have used collection of type ArrayList. It is available in the namespace System.Collections.ArrayList. When you use ArrayList, all the elements added to it will be internally converted into objects. In this case, stringList contains elements of type String which is a reference type. Hence considering it as Object will not have much overhead. But integerList stores elements of type int, which is a value type. When you add integer elements into ArrayList, each of the elements is stored as an object.

Hence it requires boxing to happen and when you retrieve elements from this integerList, unboxing has to happen. This affects performance and it has a considerable overhead. Moreover, type checking will be done only at run time and not at compile time. If your code is not type safe, no errors will be prompted by the compiler. To make it clear, consider the following example:

class sampleClass {
public static void Main( ) {
ArrayList integerList = new ArrayList( );
integerList.Add(100);
integerList.Add(“sample string1”);
integerList.Add(200);
Console.WriteLine(“Each element is incremented by 1”);
foreach (int item in integerList) {
item++;
Console.WriteLine(item);
}
}
}

As you know, this example will end up in error. But when will the error be notified? At compile time or run time? Error gets notified only at run time. There will be no compilation errors. Because type associated with the ArrayList is known only at run time. An ArrayList can accept both integer as well as string. Hence error will not be thrown. But at runtime, CLR will know that the ArrayList integerList is a collection of integers and therefore it will raise error. You have also incremented the integerList value assuming that it has only integer elements. Hence the code (item++ ;) will throw InvalidCastException.

To avoid all these above mentioned pitfalls and to provide much more advanced features, C# version 2.0 has a concept called Generics. In ArrayList you don’t mention the type of array elements explicitly. But in Generics you can declare the type along with the collection declaration. Here is an alternative code for the first example discussed in this article.

class sampleClass {
public static void Main( ) {
List<string> stringList = new List<string>( );
stringList.Add(“sample string1”);
stringList.Add(“sample string2”);
foreach (string item in stringList) {
Console.WriteLine(item);
}
List<int> integerList = new List<int>( );
integerList.Add(100);
integerList.Add(200);
foreach (int item in integerList) {
Console.WriteLine(item);
}
}
}

In this example, you have used a collection called List<Type> which is available in System.Collections.Generic namespace. Type in List<Type> refers to the type to which elements of this collection belongs to. Since the type is mentioned, you need not internally cast the elements into objects as you do in ArrayList. Hence you avoid all overheads caused due to such conversion. Since you explicitly specify the type, compiler will recognize the type of your collection and it can perform type checking for your code. Consider the following example:

class sampleClass {
public static void Main( ) {
List<int> integerList = new List<int>( );
integerList.Add(100);
integerList.Add(“sample string1”);
integerList.Add(200);
Console.WriteLine(“Each element is incremented by 1”);
foreach (int item in integerList) {
item++;
Console.WriteLine(item);
}
}
}

This code will throw compile time error. Hence you need wait till runtime to correct your code.

Not just List<Type>, you can define your own generic classes and generic methods which can yield better efficiency and reusability of your code. It also ensures type safety. Here is an example of a generic class:

public class SampleGenerics<T> {
private T element;
public SampleGenerics() {
element = null;
}
public void AssignElement(T data) {
element = data;
Console.WriteLine(element);
}
}

public class sampleClass {
public static void Main() {
SampleGenerics<int> sample = new SampleGenerics<int>();
sample.AssignElement(100);
SampleGenerics<string> sample = new SampleGenerics<string>();
sample.AssignElement(“Sample String”);
}
}

In this example you have created a generic class called SampleGenerics of type T. This class has a property called element which is of type T. And it also has a method called AssignElement which accepts parameter of type T. You finally define this type T in Main() method of sampleClass. Here you have created two instances of SampleGenerics one of type int and other of type string. Other than int, string you can also mention the type as one of the other class instances.

|Developing .Net applications for multiple locales | List of Conversion Keywords in C# |Storage and transfer of data using Serialization in .NET |C# (C Sharp) Unified Type System: Reference Types |Using Reflection at Runtime in .NET Framework |What are Generics in C# |Working with Generic Collections in .NET Framework |Working with Graphics in .Net |Working with Isolated Storage in .NET|


“Amazon and the Amazon logo are trademarks of Amazon.com, Inc. or its affiliates.”

| Privacy Policy for www.dotnet-guide.com | Disclosure | Contact |

Copyright - © 2004 - 2024 - All Rights Reserved.