HOWTO · Csharp
typedef Equivalent in C#
Learn the C# equivalent of typedef with using aliases, including C# 12 tuple aliases and ordinary aliases for generic types.
On this page
C# has no typedef keyword. The closest equivalent is a using alias, which gives a file-local name to an existing namespace or type:
The general form is using AliasName = Fully.Qualified.TypeName;.
An alias improves readability, but it does not create a new runtime type. Use a class, record, or struct when you need a distinct type with its own behavior or validation.
Use a using alias for an existing type
Place the alias with the other using directives at the top of the file. Use a fully qualified target so that the alias does not depend on another using directive:
For example, using RouteTable = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<int>>; names an existing closed generic type.
RouteTable is only a shorter spelling for Dictionary<string, List<int>>; it does not add type safety or create a new declaration. The alias is available throughout this source file, not automatically throughout the project.
The familiar forms of using have different purposes. using System.Text; imports a namespace, using static System.Math; imports static members, and using RouteTable = ...; creates an alias. Do not confuse the first two forms with a type alias.
C# 12 tuple aliases and generic type aliases
C# 12 expanded using aliases to previously unnamed type forms such as tuples. Ordinary aliases for named and constructed generic types were already supported. The following example uses both forms:
using RouteTable = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<int>>;
using Coordinate = (double Latitude, double Longitude);
RouteTable routes = new() { ["home"] = [1, 2] };
Coordinate point = (52.37, 4.90);
System.Console.WriteLine($"{routes["home"].Count}:{point.Latitude:F2}");
2:52.37
This success case was restored and built in an isolated, network-disabled .NET 10.0.401 environment using the C# 12 language feature. The project fixture was copied to temporary container storage, restored with --ignore-failed-sources, and run without changing the source fixture or the image. The alias names are still file-scoped, even though the underlying tuple and generic types can be used elsewhere without aliases.
If the project targets C# 11 or an earlier language version, do not assume that aliases for arbitrary type forms will compile. Upgrade the language/toolchain or use the fully written type. The ordinary alias form for named types predates C# 12.
What an alias does not do
An alias is not a typedef-style distinct type. RouteTable and its full dictionary type are interchangeable at compile time. Code that needs a value which cannot accidentally be passed where another value is expected should use a real domain type, such as a record or readonly struct, rather than an alias.
Likewise, a tuple alias gives a readable name to a tuple shape; it does not turn that tuple into a named class. Tuple element names improve access and documentation, but they do not provide independent type identity.
Nullable-reference alias targets are a boundary
The expanded alias grammar still has restrictions. A top-level nullable reference type is not a permitted alias target. For example, this is intentionally invalid:
The invalid declaration is using MaybeName = string?;.
The compiler rejects the alias declaration because string? is a nullable-reference annotation, not an allowed alias target in this position. The boundary fixture is expected to fail compilation; it is diagnostic evidence, not a runnable solution. Use an allowed underlying type in the alias, and express nullability on the member, parameter, or variable where the alias is used.
When to define a real type instead
Choose a class, record, or struct when the name must represent a distinct concept. A real type is appropriate when you need invariants, validation, methods, controlled construction, equality semantics, or a public API that should not expose the implementation type directly. A using alias is better when you only need a shorter file-local spelling for a long type, tuple, or closed generic type.
For the official syntax and version details, see the Microsoft documentation for the using directive, what is new in C# 12, and the C# 12 using-alias proposal.
FAQ
- Does C# support
typedef? No. Use ausingalias for a shorter name, or define a real type when you need type identity. - Can an alias target a tuple? Yes, with C# 12 or later.
- Is an alias available in every file? No. A normal alias is scoped to the file that declares it.
- Does an alias create a new type? No. It refers to the existing target type.
- Why does
using MaybeName = string?;fail? A top-level nullable-reference target is prohibited for ausingalias, so the compiler reports a declaration error.