116

I'm new to C# and directly diving into modifying some code for a project I received. However, I keep seeing code like this :

class SampleCollection<T>

and I cannot make sense of what the

<T> 

means nor what it is called.

If anyone would care to help me just name what this concept is called, I can search it online. However, I'm clueless as of now.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
YD8877
  • 10,401
  • 20
  • 64
  • 92
  • Dupe of http://stackoverflow.com/questions/361336/what-are-generic-collections-in-c#361365 and http://stackoverflow.com/questions/400314/what-does-t-mean-in-c. – Abel Mar 25 '12 at 18:33
  • 1
    Duplicate of many others, but also off-topic like the others because it's asking for a [documentation](http://msdn.microsoft.com/en-us/library/512aeb7t.aspx) or tutorial. – Tim Schmelter Sep 15 '14 at 19:32

3 Answers3

154

It is a Generic Type Parameter.

A generic type parameter allows you to specify an arbitrary type T to a method at compile-time, without specifying a concrete type in the method or class declaration.

For example:

public T[] Reverse<T>(T[] array)
{
    var result = new T[array.Length];
    int j=0;
    for(int i=array.Length - 1; i>= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}

reverses the elements in an array. The key point here is that the array elements can be of any type, and the function will still work. You specify the type in the method call; type safety is still guaranteed.

So, to reverse an array of strings:

string[] array = new string[] { "1", "2", "3", "4", "5" };
var result = Reverse(array);

Will produce a string array in result of { "5", "4", "3", "2", "1" }

This has the same effect as if you had called an ordinary (non-generic) method that looks like this:

public string[] Reverse(string[] array)
{
    var result = new string[array.Length];
    int j=0;
    for(int i=array.Length - 1; i >= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}

The compiler sees that array contains strings, so it returns an array of strings. Type string is substituted for the T type parameter.


Generic type parameters can also be used to create generic classes. In the example you gave of a SampleCollection<T>, the T is a placeholder for an arbitrary type; it means that SampleCollection can represent a collection of objects, the type of which you specify when you create the collection.

So:

var collection = new SampleCollection<string>();

creates a collection that can hold strings. The Reverse method illustrated above, in a somewhat different form, can be used to reverse the collection's members.

Rune Vejen Petersen
  • 3,201
  • 2
  • 30
  • 46
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • in what way can a generic type parameter T be specified at runtime? – Mike Zboray Mar 25 '12 at 01:35
  • 1
    @mikez: http://stackoverflow.com/questions/513952/c-sharp-specifying-generic-collection-type-param-at-runtime – Kendall Frey Mar 25 '12 at 01:41
  • 2
    Yes, though you can instantiate generic classes with a type parameter at runtime using reflection, it is confusing to say that you use generics to specify a type at runtime where you under normal use specify one at compile time. – SoftMemes Mar 25 '12 at 01:43
  • But the question seems to be about generic types, not about generic methods. – svick Mar 25 '12 at 03:13
  • @svick: The generic method is just an example of how the generic type can be used. However, I added some clarification for the OP's original bit of code. – Robert Harvey Mar 25 '12 at 03:15
  • @RobertHarvey, I don't see any generic type in any of your code samples. If you mean that the `Reverse()` method is inside a generic class, then it shouldn't have the type parameter itself. – svick Mar 25 '12 at 03:17
  • @SoftMemes: One can create generic types at runtime even without reflection. For example, a method in class `Foo` could create an instance of `Foo>` or `Foo>`, or a function `Foo` could decide to call `Foo>` or `Foo>` based upon a parameter value. There is no fixed set of types which the program might need, so the runtime would have to create the types as they are needed. – supercat Dec 23 '13 at 17:20
  • whats the advantage when using `````` in interfaces? – ulkas Mar 08 '19 at 10:08
  • 1
    @ulkas: From [here](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-interfaces): *"The preference for generic classes is to use generic interfaces, such as IComparable rather than IComparable, in order to avoid boxing and unboxing operations on value types."* – Robert Harvey Mar 08 '19 at 15:11
41

It is a generic type parameter, see Generics documentation.

T is not a reserved keyword. T, or any given name, means a type parameter. Check the following method (just as a simple example).

T GetDefault<T>()
{
    return default(T);
}

Note that the return type is T. With this method you can get the default value of any type by calling the method as:

GetDefault<int>(); // 0
GetDefault<string>(); // null
GetDefault<DateTime>(); // 01/01/0001 00:00:00
GetDefault<TimeSpan>(); // 00:00:00

.NET uses generics in collections, ... example:

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

This way you will have a list that only accepts integers, because the class is instancited with the type T, in this case int, and the method that add elements is written as:

public class List<T> : ...
{
    public void Add(T item);
}

Some more information about generics.

You can limit the scope of the type T.

The following example only allows you to invoke the method with types that are classes:

void Foo<T>(T item) where T: class
{
}

The following example only allows you to invoke the method with types that are Circle or inherit from it.

void Foo<T>(T item) where T: Circle
{
}

And there is new() that says you can create an instance of T if it has a parameterless constructor. In the following example T will be treated as Circle, you get intellisense...

void Foo<T>(T item) where T: Circle, new()
{
    T newCircle = new T();
}

As T is a type parameter, you can get the object Type from it. With the Type you can use reflection...

void Foo<T>(T item) where T: class
{
    Type type = typeof(T);
}

As a more complex example, check the signature of ToDictionary or any other Linq method.

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

There isn't a T, however there is TKey and TSource. It is recommended that you always name type parameters with the prefix T as shown above.

You could name TSomethingFoo if you want to.

NoWar
  • 36,338
  • 80
  • 323
  • 498
BrunoLM
  • 97,872
  • 84
  • 296
  • 452
11

This feature is known as generics. http://msdn.microsoft.com/en-us/library/512aeb7t(v=vs.100).aspx

An example of this is to make a collection of items of a specific type.

class MyArray<T>
{
    T[] array = new T[10];

    public T GetItem(int index)
    {
        return array[index];
    }
}

In your code, you could then do something like this:

MyArray<int> = new MyArray<int>();

In this case, T[] array would work like int[] array, and public T GetItem would work like public int GetItem.

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148