Visual Studio 2005 also introduces the next version of C#. C# 2.0 introduces generics, iterators, partial class definitions, nullable types, anonymous methods, the :: operator, static classes, accessor accessibility, fixed sized buffers (unsafe), friend assemblies, and #pragma warnings.

Generic types allow for the reuse of code and enhanced performance for collection classes (due to boxing and unboxing issues).

Generics are classes that are not type specific. For example, instead creating a Stack class for integers, another one for floats, you can create a generic class. The way this was done in the past was to create classes that just took objects. But, this lacks compile-time type checking. Everything is done at run-time.

// File: StackObject.cs
using System;
class Stack
{
    object[] stack;
    int top;
    public Stack(int size)
    {
        stack = new object[size];
        top = 0;
    }
    public object Pop()
    {
        return stack[--top];
    }
    public void Push(object v)
    {
        stack[top++] = v;
    }
}
class Program
{
    static void Main()
    {
        Stack stack = new stack(10);
        // Performance hit, boxing!!!
        stack.Push(5);
        stack.Push(10);
        // Another perf hit, unboxing!!!
        int top = (int)stack.Pop();
    }
}

By using generics, you can eliminate the boxing and unboxing.

// File: StackGeneric.cs
using System;
class Stack<T>
{
    T[] stack;
    int top;
    public Stack(int size)
    {
        stack = new T[size];
        top = 0;
    }
    public T Pop()
    {
        return stack[--top];
    }
    public void Push(T v)
    {
        stack[top++] = v;
    }
}
class Program
{
    static void Main()
    {
        Stack<int> intStack = new Stack<int>(10);
        intStack.Push(5);
        intStack.Push(5);
        int top = intStack.Pop();
    }
}