Hi lovely readers,
Have you ever found yourself typing the same type name twice when creating an object in C#? For example Person person = new Person(); feels a little repetitive, doesn’t it?
Modern C# fixes this small annoyance with a simple but powerful feature called target-typed new. It helps you write cleaner, shorter, and more readable code while keeping everything strongly typed.
In this blog post, we are going to explore target-typed new, when to use it, and how it can make your code a little bit nicer to look at.
Does your application create a lot of objects? Do you like tidy syntax and less typing? Continue reading and I’ll show you how.
Why target-typed new
Cleaner code
Target-typed new lets the compiler infer the type from the context. You no longer have to repeat it.
// Before
Person person = new Person("Alice", 30);
// Now
Person person = new("Alice", 30);
The compiler already knows the type on the left side, so you can safely skip it on the right.
Works with fields and properties
You can use it for field or property initialization too.
private readonly HttpClient _client = new();
private List<string> _items = new();
Great for readability with long type names
It really shines when dealing with complex or generic types.
Dictionary<string, List<int>> data = new();
Queue<(int Id, string Name)> queue = new();
Still fully typed
This is not dynamic or weak typing. The compiler still checks everything, exactly like before.
How to use target-typed new
Target-typed new works whenever the compiler can infer the type of the object from context. That includes variable declarations, field initializers, property initializers, and even return statements.
Variable declarations
Person person = new("Bob", 25);
Car car = new("Tesla", "Model 3");
Properties and fields
public class Library
{
public List<string> Books { get; } = new();
private readonly HttpClient _client = new();
}
Return statements
When the method return type is known, you can use target-typed new in returns too.
static Point CreatePoint() => new(10, 20);
Limitations
Target-typed new only works when the compiler can clearly determine the type. If the type is ambiguous, you’ll get an error.
var item = new(); // ❌ Error: cannot infer the type
It also doesn’t work with anonymous types or cases where there’s no obvious target type.
Comparing var and target-typed new
Both var and target-typed new reduce repetition, but they do it differently.
| Style | Example | How type is inferred |
|---|---|---|
var |
var p = new Person("Alice"); |
From the right-hand side |
Target-typed new
|
Person p = new("Alice"); |
From the left-hand side |
Use whichever makes the code clearer in that context. var is great when the type on the right is obvious. Target-typed new is better when you want to make the type explicit but avoid repeating it.
A few more examples
List<int> numbers = new() { 1, 2, 3, 4 };
CancellationTokenSource cts = new();
Tuple<int, string> pair = new(1, "hello");
Each of these lines is shorter, cleaner, and easier to scan.
That’s a wrap
Target-typed new helps remove small bits of repetition and keeps your codebase neat. It’s one of those small features that doesn’t change how C# works but makes writing and reading code more enjoyable.
Whether you’re defining data models, initializing services, or just cleaning up long generic types, target-typed new makes your code look modern and elegant.
I hope this post helped you understand target-typed new in modern C#. If you have any questions or comments, feel free to reach out on @lovelacecoding on pretty much every social media platform or leave a comment down below.
See ya!
Top comments (0)