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

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

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

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

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