C# tutorials > Modern C# Features > C# 6.0 and Later > Explain target-typed `new` expressions in C# 9.0 with an example.

Explain target-typed `new` expressions in C# 9.0 with an example.

C# 9.0 introduced target-typed new expressions, a feature that simplifies object instantiation when the type of the object is already known from the context. This eliminates redundant type declarations and makes code cleaner and more readable. This tutorial explains target-typed new expressions with examples, use cases, and best practices.

Introduction to Target-Typed `new` Expressions

Prior to C# 9.0, when creating an object, you had to specify the type on both sides of the assignment. For example:

MyClass myObject = new MyClass();

With target-typed new expressions, you can omit the type on the right-hand side if the compiler can infer it from the left-hand side:

MyClass myObject = new(); // Target-typed new expression

This makes the code less verbose, especially when dealing with complex type names or generic types.

Basic Example

In this example, we create a Person object using the target-typed new expression. The compiler infers that new() should create a Person object because the variable person is of type Person.

using System;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public override string ToString()
    {
        return $"Name: {Name}, Age: {Age}";
    }
}

public class Example
{
    public static void Main(string[] args)
    {
        // Using target-typed new expression
        Person person = new("Alice", 30);

        Console.WriteLine(person);
    }
}

Concepts Behind the Snippet

The key concept is type inference. The compiler looks at the context in which the new expression is used and determines the type of the object being created. This works when the type is clearly defined by the variable declaration, method return type, or other contextual information.

Real-Life Use Case: Collections

Target-typed new is particularly useful when initializing collections. Instead of repeating the collection type, you can use new().

using System.Collections.Generic;

public class Example
{
    public static void Main(string[] args)
    {
        // Using target-typed new with a List
        List<string> names = new() { "Bob", "Charlie", "David" };

        foreach (var name in names)
        {
            System.Console.WriteLine(name);
        }
    }
}

Real-Life Use Case: Method Return Values

This is also helpful in methods that return new instances of classes where the return type is already specified in the method signature.

public class Example
{
    public static Person CreatePerson(string name, int age)
    {
        return new(name, age); // Target-typed new in a return statement
    }

    public static void Main(string[] args)
    {
        var person = CreatePerson("Eve", 25);
        System.Console.WriteLine(person);
    }
}

Best Practices

  • Use consistently: If you start using target-typed new expressions, apply them consistently throughout your codebase for readability.
  • Clarity is key: Ensure the type is clearly inferred from the context. Avoid using target-typed new if it makes the code ambiguous.
  • Consider readability: While shorter, make sure the code remains easy to understand and maintain.

When to use them

Use target-typed new expressions when:

  • The type is immediately apparent from the variable declaration or assignment context.
  • You want to reduce boilerplate code and improve readability.
  • The type is complex or contains generics.

Alternatives

The alternative to target-typed new is explicitly specifying the type when creating the object:

MyClass myObject = new MyClass();

This is more verbose but can be clearer in some situations where type inference isn't immediately obvious.

Pros

  • Reduced boilerplate: Less typing is required.
  • Improved readability: Code becomes cleaner, especially with complex types.
  • Conciseness: Makes the code more compact.

Cons

  • Potential ambiguity: Can reduce readability if the type isn't immediately obvious.
  • Compiler dependency: Requires C# 9.0 or later.

Memory footprint

Target-typed new expressions do not inherently affect the memory footprint of your application. They are a syntactic sugar that the compiler resolves at compile time, generating the same IL code as if you had explicitly specified the type. The amount of memory allocated for the object remains the same; only the way you write your code changes.

Interview Tip

Be prepared to discuss the benefits and drawbacks of target-typed new expressions, and provide examples of when they should be used and when they should be avoided. Understand that the compiler infers the type from the context, and this can lead to cleaner and more readable code.

FAQ

  • Does target-typed `new` affect performance?

    No, target-typed new is a compile-time feature that doesn't impact runtime performance. The compiler infers the type and generates the same IL code as if you had specified the type explicitly.
  • Is target-typed `new` available in older versions of C#?

    No, target-typed new was introduced in C# 9.0. You need to use a C# 9.0 or later compiler to use this feature.
  • Can I use target-typed `new` with anonymous types?

    No, target-typed new cannot be used with anonymous types because the compiler cannot infer the type from the context in those scenarios.