C#
generics
`````<T>`````
programming
software development

What does T denote in C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, T inside generic syntax such as List<T> or void Save<T>(T value) is a type parameter. It is not a special keyword with built-in runtime meaning. It is just a conventional placeholder name that stands for "some type to be supplied later." The compiler uses that placeholder to generate type-safe reusable code.

T As A Type Parameter

A generic type or method can be written once and used with many concrete types.

csharp
1using System;
2
3class Box<T>
4{
5    public T Value { get; }
6
7    public Box(T value)
8    {
9        Value = value;
10    }
11}
12
13class Program
14{
15    static void Main()
16    {
17        var intBox = new Box<int>(42);
18        var stringBox = new Box<string>("hello");
19
20        Console.WriteLine(intBox.Value);
21        Console.WriteLine(stringBox.Value);
22    }
23}

Here T means "whatever type the caller chooses." When you create Box<int>, T becomes int. When you create Box<string>, T becomes string.

The letter T is conventional because it stands for "type," but the compiler would accept another name such as TItem or TValue.

Why Generics Use Placeholders

Without generics, reusable containers and APIs would either:

  • use object and require casts later
  • duplicate code for each concrete type

Generics solve both problems. They keep the API reusable and still preserve compile-time type checking.

csharp
1using System;
2using System.Collections.Generic;
3
4class Program
5{
6    static void Main()
7    {
8        List<int> numbers = new List<int> { 1, 2, 3 };
9        int first = numbers[0];
10        Console.WriteLine(first);
11    }
12}

List<int> returns int values directly. There is no cast from object and no boxing for normal list access.

T In Generic Methods

T is not limited to classes. Methods can use it too.

csharp
1using System;
2
3class Program
4{
5    static T Echo<T>(T value)
6    {
7        return value;
8    }
9
10    static void Main()
11    {
12        Console.WriteLine(Echo(123));
13        Console.WriteLine(Echo("world"));
14    }
15}

The compiler can infer the type argument here, so Echo(123) is treated as Echo<int>(123).

That is why generic code often feels natural after the first few examples. The type parameter is present even when you do not write it explicitly.

More Descriptive Names Than T

While T is common, many APIs use more informative names when there are several type parameters.

csharp
using System.Collections.Generic;

Dictionary<string, int> wordCounts = new Dictionary<string, int>();

The generic definition of Dictionary uses names like TKey and TValue. Those are still type parameters, just with clearer intent.

You can do the same in your own code.

csharp
1class Pair<TLeft, TRight>
2{
3    public TLeft Left { get; set; }
4    public TRight Right { get; set; }
5}

T is only a convention, not a requirement.

Generic Constraints

Sometimes a type parameter must satisfy certain rules. Constraints express that.

csharp
1using System;
2
3class Factory<T> where T : new()
4{
5    public T Create()
6    {
7        return new T();
8    }
9}

The where T : new() constraint says the type argument must have a public parameterless constructor. Other constraints include class, struct, base classes, and interfaces.

Constraints matter because they tell the compiler what operations are valid on T.

Common Pitfalls

A common beginner mistake is thinking T is a built-in type or a runtime variable. It is neither. It is a compile-time type parameter.

Another mistake is assuming the name must be exactly T. It does not. T, TItem, and TResult are all legal names for type parameters.

Developers also sometimes write generic code without constraints and then wonder why they cannot call certain members on T. If the compiler does not know what T supports, it cannot allow those operations.

Finally, avoid choosing generic type parameter names that hide intent. TKey and TValue are often clearer than two unnamed T-style placeholders.

Summary

  • In C#, T is usually a generic type parameter.
  • It stands for a type that will be supplied later, such as int or string.
  • 'T is a naming convention, not a special keyword.'
  • Generic classes and methods use type parameters to provide reusable, type-safe code.
  • Constraints such as where T : new() limit which types can be used.
  • Descriptive names like TKey and TValue are often better when multiple type parameters are involved.

Course illustration
Course illustration

All Rights Reserved.