1. What are generics?
2. Advantages of using generics?
Generic is a way to define a generalized algorithm which will be able to work with many different types without rewriting source code.
1. Source code protection. Compare to the C++ templates to use generics no need to have its source code.
2. Type safety. When we use generics the C# compiler is able to check type in the compile time.
3. Better readability.
4. Better performance. As we can see in the code below using generics we can avoid boxing and unboxing and decrease number of times when garbage collection will be called and thus improve the performance.
Example:
public sealed class PerformanceGauge : IDisposable
{
private Stopwatch _stopWatch = null;
private int _collectionCount = 0;
private PerformanceGauge() { }
public PerformanceGauge(string testName)
{
CollectGC();
_collectionCount = GC.CollectionCount(0);
Trace.WriteLine(testName);
_stopWatch = new Stopwatch();
_stopWatch.Start();
}
#region IDisposable Members
public void Dispose()
{
_stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = _stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Trace.WriteLine(elapsedTime);
string timesOccured = String.Format("GC collection was ocurred for {0} times", GC.CollectionCount(0) – _collectionCount);
Trace.WriteLine(elapsedTime);
Trace.WriteLine(timesOccured);
}
#endregion
private void CollectGC()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
class Program
{
static void Main(string[] args)
{
int count = 10000000;
NonGenericWithValueTypeTest(count);
NonGenericWithReferenceTypeTest(count);
GenericWithValueTypeTest(count);
GenericWithReferenceTypeTest(count);
Console.ReadKey();
}
private static void NonGenericWithValueTypeTest(int count)
{
using (PerformanceGauge gauge = new PerformanceGauge("NonGenericWithValueTypeTest"))
{
ArrayList list = new ArrayList();
for (int i = 0; i < count; i++)
{
list.Add(i);
int n = (int)list[i];
}
list = null;
}
}
private static void NonGenericWithReferenceTypeTest(int count)
{
using (PerformanceGauge gauge = new PerformanceGauge("NonGenericWithReferenceTypeTest"))
{
ArrayList list = new ArrayList(count);
for (int i = 0; i < count; i++)
{
list.Add("x");
string n = (string)list[i];
}
list = null;
}
}
private static void GenericWithValueTypeTest(int count)
{
using (PerformanceGauge gauge = new PerformanceGauge("GenericWithValueTypeTest"))
{
List<int> list = new List<int>(count);
for (int i = 0; i < count; i++)
{
list.Add(i);
int n = list[i];
}
list = null;
}
}
private static void GenericWithReferenceTypeTest(int count)
{
using (PerformanceGauge gauge = new PerformanceGauge("NonGenericWithReferenceTypeTest"))
{
List<string> list = new List<string>(count);
for (int i = 0; i < count; i++)
{
list.Add("x");
string n = list[i];
}
list = null;
}
}
}
Output:
NonGenericWithValueTypeTest
00:00:02.99
00:00:02.99
GC collection was ocurred for 30 times
NonGenericWithReferenceTypeTest
00:00:00.33
00:00:00.33
GC collection was ocurred for 0 times
GenericWithValueTypeTest
00:00:00.17
00:00:00.17
GC collection was ocurred for 0 times
NonGenericWithReferenceTypeTest
00:00:00.24
00:00:00.24
GC collection was ocurred for 0 times