C# バージョンごとの新機能まとめ

2024年12月24日

C#は、2000年に最初のバージョンがリリースされて以来、継続的な進化を遂げているプログラミング言語です。各バージョンでは、新しい機能や改善が導入されており、開発者がより効率的に、安全で柔軟なコードを書けるように設計されています。この技術資料では、C# 2.0からC# 12に至るまでの主な新機能を紹介し、シンプルなサンプルコードと共にその使い方を説明します。

この資料は、C#の基本を習得した方や、各バージョンの新機能について理解を深めたい方を対象としています。バージョンごとの機能変遷を通じて、C#の柔軟性と拡張性を体感し、日々のプログラミングに活かしていただけることを期待しています。

進化し続けるC#の機能を学ぶことは、日常的なプログラムの保守や開発効率の向上に役立ちます。特に、ジェネリクスやLINQ、非同期処理のような強力なツールは、コードの簡潔さとパフォーマンスの向上に寄与します。また、Null許容型やレコード型、非同期メソッドなど、最新バージョンの機能は、より安全でモダンなコーディングスタイルを提供します。

C#のバージョンと主な機能

以下に、C#の各バージョンと主な新機能をまとめた表を示します。

バージョンリリース年主な新機能
C# 1.02002年– 基本的なオブジェクト指向機能の提供
C# 2.02005年– ジェネリック
– 匿名メソッド
– イテレーター
– 部分クラス
– null許容型
C# 3.02007年– ラムダ式
– 拡張メソッド
– 式木
– 匿名型
– オブジェクト初期化子
– コレクション初期化子
– 自動実装プロパティ
– クエリ式(LINQ)
C# 4.02010年– 動的型(dynamic
– 名前付き引数と省略可能な引数
– ジェネリックの共変性と反変性
– 埋め込み相互運用機能型
C# 5.02012年– 非同期プログラミングのサポート(async/await
– 呼び出し元情報属性
C# 6.02015年– 静的インポート
– 例外フィルター
– 自動プロパティ初期化子
– 式形式のメンバー
– Null条件演算子
– 文字列補間
nameof 演算子
C# 7.02017年– タプルと分解
– パターンマッチング
– ローカル関数
ref ローカル変数と戻り値
out 変数の宣言
C# 7.12017年– 非同期メインメソッド
– デフォルトリテラル式
– 推論されたタプル要素名
– ジェネリック型パラメーターのパターンマッチング
C# 7.22017年in パラメーター
ref 構造体
private protected アクセス修飾子
– 数値リテラルの先頭アンダースコア
C# 7.32018年– スタック割り当て配列の初期化子
– より強力なジェネリック制約
– タプルの等値比較
C# 8.02019年– 読み取り専用メンバー
– 既定のインターフェイスメソッド
– パターンマッチングの拡張(switch 式、プロパティパターン、タプルパターン)
using 宣言
– 静的ローカル関数
– 非同期ストリーム
– インデックスと範囲
– Null許容参照型
C# 9.02020年– レコード型
– with式
– init専用セッター
– トップレベルステートメント
– パターンマッチングの強化
– 静的匿名関数
C# 10.02021年– グローバルusingディレクティブ
– ファイルスコープの名前空間宣言
– 拡張されたパターンマッチング
– レコード構造体
with 式の改良
C# 11.02022年– Raw文字列リテラル
– 一般化された属性ターゲット
– 静的メンバーの抽象化
– UTF-8文字列リテラル
C# 12.02023年– プライマリコンストラクターのクラスと構造体への拡張
– コレクション式
ref readonly パラメーター
– ラムダ式の省略可能なパラメーター
– 任意の型の別名設定
– インライン配列
– 試験段階の属性
– インターセプター
C# 13.02024年– 新しいエスケープシーケンス(\e
– メソッドグループでの自然型の改善
– オブジェクト初期化子での暗黙的なインデクサーアクセス

C# 2.0: ジェネリクス

説明

ジェネリクスを使用することで、型に依存しない汎用的なクラスやメソッドを作成できます。これにより、異なるデータ型で動作するコードを一つのクラスやメソッドで表現できます。

サンプルコード

public class GenericClass<T>
{
    public T Value { get; set; }
}

var intGeneric = new GenericClass<int> { Value = 10 };
var stringGeneric = new GenericClass<string> { Value = "Hello" };

C# 3.0: LINQ, 型推論 (var), 拡張メソッド

説明

  • LINQ: コレクションに対するクエリ操作を簡潔に書ける。
  • 型推論 (var): 型を推論して自動的に決定。
  • 拡張メソッド: 既存の型に対して新しいメソッドを追加できます。

サンプルコード

using System;
using System.Collections.Generic;
using System.Linq;

public static class Extensions
{
    public static void Print(this string str)
    {
        Console.WriteLine(str);
    }
}

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);

foreach (var number in evenNumbers)
{
    Console.WriteLine(number);
}

"Hello, C# 3.0".Print();

C# 5.0: 非同期処理 (async/await)

説明

非同期メソッドの実行により、アプリケーションが応答を維持しながら、時間のかかる処理をバックグラウンドで実行できます。

サンプルコード

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        await DoSomethingAsync();
        Console.WriteLine("Completed!");
    }

    public static async Task DoSomethingAsync()
    {
        await Task.Delay(1000);
        Console.WriteLine("Async task completed.");
    }
}

C# 6.0: Null 条件演算子 (?.), 文字列挿入 ($"{a}")

説明

  • Null 条件演算子: オブジェクトが null かどうかを簡単に確認できます。
  • 文字列挿入: $"{変数}" を使うことで、簡潔に変数や式を文字列に埋め込めます。

サンプルコード

string name = null;
Console.WriteLine(name?.ToUpper() ?? "Name is null");

int a = 10;
int b = 20;
Console.WriteLine($"a + b = {a + b}");

C# 7.0: タプル (ValueTuple)

説明

タプルを使って複数の値をまとめて返したり、操作したりできます。

サンプルコード

(int x, int y) coordinates = (10, 20);
Console.WriteLine($"X: {coordinates.x}, Y: {coordinates.y}");

C# 8.0: Null 許容参照型 (T?), switch 式, Interface デフォルト実装

説明

  • Null 許容参照型: 参照型に null を許可できる。
  • switch: switch 文をより簡潔に書ける。
  • Interface デフォルト実装: インターフェースでデフォルトの実装を提供できる。

サンプルコード

#nullable enable
string? name = null;
Console.WriteLine(name?.ToUpper() ?? "Name is null");

int number = 5;
string result = number switch
{
    1 => "One",
    2 => "Two",
    _ => "Other"
};
Console.WriteLine(result);

public interface IExample
{
    void Show() => Console.WriteLine("Default implementation");
}

C# 9.0: record 型, with 式, トップレベルステートメント

説明

  • record: 不変データのモデル化に適した型。
  • with: record オブジェクトを簡単にコピーして変更可能。
  • トップレベルステートメント: Main メソッドを省略してプログラムを簡潔に記述。

サンプルコード

public record Person(string FirstName, string LastName);

var person1 = new Person("John", "Doe");
var person2 = person1 with { LastName = "Smith" };
Console.WriteLine(person2);

// トップレベルステートメント
Console.WriteLine("Hello from C# 9.0!");

C# 10: ファイルスコープ namespace, global using

説明

  • ファイルスコープ namespace: namespace ブロックを省略してファイル全体に適用。
  • global using: using ディレクティブを全てのファイルで共有できる。

サンプルコード

// ファイルスコープ namespace
namespace MyApp;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello from C# 10.0!");
    }
}

// global using
// ファイルの先頭に記述 (一度設定すると全てのファイルで有効)
global using System;
global using System.Collections.Generic;

C# 11: 生文字列リテラル

説明

生文字列リテラルを使うことで、複数行の文字列やエスケープ文字をそのまま表現できます。

サンプルコード

string rawString = """
This is a "raw" string.
It spans multiple lines and preserves formatting.
""";
Console.WriteLine(rawString);

C# 12: コレクション式, プライマリコンストラクタ

説明

  • コレクション式: 配列やリストの初期化を簡単に書ける。
  • プライマリコンストラクタ: クラスのプロパティ初期化を簡潔に記述。

サンプルコード

// コレクション式
var numbers = [1, 2, 3, 4];
Console.WriteLine(string.Join(", ", numbers));

// プライマリコンストラクタ
public class MyClass(int PropA, int PropB)
{
    public void PrintProperties() => Console.WriteLine($"PropA: {PropA}, PropB: {PropB}");
}

var myObj = new MyClass(10, 20);
myObj.PrintProperties();

C#

Posted by hidepon