[C#] Omitting Type Names in Instance Creation with Target-Typed New Expressions

Introduced in C# 9.0, Target-typed new expressions allow you to omit the type description when creating an instance and simply write new() provided the compiler can infer the type from the context.

Previously, code tended to become verbose when instantiating classes with long names or generic types. Using this feature reduces the amount of code and improves readability.

In this article, I will explain specific usage methods using a factory method that generates a configuration class for retry processing as an example.

目次

Table of Contents

  1. Examples of Use
  2. Comparison with Previous Syntax
  3. Complete Implementation Code
  4. Use Cases and Benefits
  5. Summary

Examples of Use

The following code defines a RetryPolicy class that manages communication retry counts and intervals, and uses a target-typed new expression in the method that generates it.

Comparison with Previous Syntax

  • Traditional (C# 8.0 and earlier): Even if the return type was fixed, you had to explicitly state the type name, like return new RetryPolicy { ... }.
  • Current (C# 9.0 and later): Since the type can be inferred from the return type, you can write return new() { ... }.

Complete Implementation Code

using System;

namespace NewExpressionExample
{
    // Class to manage retry settings
    public class RetryPolicy
    {
        // Retry count
        public int MaxRetryCount { get; set; }

        // Retry interval (milliseconds)
        public int IntervalMilliseconds { get; set; }

        public override string ToString()
        {
            return $"Retry Count: {MaxRetryCount}, Interval: {IntervalMilliseconds}ms";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 1. Use in method return values
            // Since the type is clear from the method definition, new() can be used internally
            RetryPolicy defaultPolicy = CreateDefaultPolicy();
            Console.WriteLine("Default Settings: " + defaultPolicy);

            // 2. Use in variable declaration
            // Since the type is explicit on the left side, the right side only needs new()
            RetryPolicy customPolicy = new()
            {
                MaxRetryCount = 5,
                IntervalMilliseconds = 2000
            };
            Console.WriteLine("Custom Settings: " + customPolicy);

            // Reference: When using var (Traditional type inference)
            // Since the left side is inferred, the type is required on the right side
            var legacyStyle = new RetryPolicy { MaxRetryCount = 1, IntervalMilliseconds = 500 };
        }

        // Factory Method
        public static RetryPolicy CreateDefaultPolicy()
        {
            // Since it is clear that the return type is RetryPolicy, 
            // we can omit the type name and write new()
            return new()
            {
                MaxRetryCount = 3,
                IntervalMilliseconds = 1000
            };
        }
    }
}

Use Cases and Benefits

Target-typed new expressions are particularly effective in the following situations:

  • Field and Property Initialization:C#private Dictionary<string, List<int>> _data = new(); You avoid having to write long generic type names twice.
  • Method Arguments:C#ProcessData(new() { Id = 1, Name = "Test" }); If the type is determined by the method signature, you can omit the type name when creating and passing the object in the argument list.
  • Combination with Object Initializers: As shown in the example, when generating an object while setting properties, the area after new becomes cleaner, making it easier to focus on the setting values (properties).

Summary

The concise new() syntax is effective for reducing code noise. However, since it has an opposite relationship with the var keyword (explicit left side vs. explicit right side), it is good to have a policy within your team on which one to prioritize or how to use them depending on the situation.

Generally, it is recommended to actively use new() in places where the type is explicit, such as field definitions and method return values or arguments.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次