C# 9.0 で導入された「ターゲット型 new 式(Target-typed new expressions)」を使用すると、コンパイラが型を推論できる文脈において、インスタンス生成時の型記述を省略し、単に new() と記述することができます。
従来、型名が長いクラスやジェネリック型をインスタンス化する際、コードが冗長になりがちでした。この機能を利用することで、記述量を減らし、可読性を向上させることができます。
本記事では、リトライ処理の設定クラスを生成するファクトリーメソッドを例に、具体的な使用方法を解説します。
目次
ターゲット型new式の活用例
以下のコードは、通信のリトライ回数や間隔を管理する設定クラス RetryPolicy を定義し、それを生成するメソッドでターゲット型 new 式を活用した例です。
以前の書き方との比較
- 従来 (C# 8.0 以前): 戻り値の型が決まっていても、
return new RetryPolicy { ... }と型名を明記する必要がありました。 - 現在 (C# 9.0 以降): 戻り値の型から推論可能なため、
return new() { ... }と記述できます。
完全な実装コード
using System;
namespace NewExpressionExample
{
// リトライ設定を管理するクラス
public class RetryPolicy
{
// リトライ回数
public int MaxRetryCount { get; set; }
// リトライ間隔(ミリ秒)
public int IntervalMilliseconds { get; set; }
public override string ToString()
{
return $"リトライ回数: {MaxRetryCount}回, 間隔: {IntervalMilliseconds}ms";
}
}
class Program
{
static void Main(string[] args)
{
// 1. メソッドの戻り値での利用
// メソッドの定義で型が明確なため、内部で new() が使える
RetryPolicy defaultPolicy = CreateDefaultPolicy();
Console.WriteLine("デフォルト設定: " + defaultPolicy);
// 2. 変数宣言時の利用
// 左辺で型を明示している場合、右辺は new() だけで良い
RetryPolicy customPolicy = new()
{
MaxRetryCount = 5,
IntervalMilliseconds = 2000
};
Console.WriteLine("カスタム設定: " + customPolicy);
// 参考: varを使う場合(従来の型推論)
// 左辺を推論させるため、右辺には型が必要
var legacyStyle = new RetryPolicy { MaxRetryCount = 1, IntervalMilliseconds = 500 };
}
// ファクトリーメソッド
public static RetryPolicy CreateDefaultPolicy()
{
// 戻り値の型が RetryPolicy であることは明白なため、
// 型名を省略して new() と記述できる
return new()
{
MaxRetryCount = 3,
IntervalMilliseconds = 1000
};
}
}
}
使用する場面とメリット
ターゲット型 new 式は、以下のような場面で特に効果を発揮します。
- フィールドやプロパティの初期化:C#
private Dictionary<string, List<int>> _data = new();ジェネリック型のような長い型名を二度書かずに済みます。 - メソッドの引数:C#
ProcessData(new() { Id = 1, Name = "Test" });メソッドのシグネチャから型が確定している場合、引数部分で型名を省略してオブジェクトを作成・渡すことができます。 - オブジェクト初期化子との組み合わせ: 今回の例のように、プロパティを設定しながら生成する場合、
newの後ろがすっきりとし、設定値(プロパティ)に目が向きやすくなります。
まとめ
new() という簡潔な記述は、コードのノイズを減らすのに有効です。ただし、var キーワード(型推論)とは対になる関係(左辺を明示するか、右辺を明示するか)であるため、チーム内でどちらを優先するか、あるいは状況に応じて使い分けるかの方針を持っておくと良いでしょう。
一般的には、「フィールド定義」や「メソッドの戻り値・引数」など、型が明示されている場所では new() を積極的に使用することが推奨されます。
