C#-8

C#の学習、お疲れ様でした!前回の非同期プログラミングで、C#の主要なトピックは一通り網羅できました。

ここからは、これらの知識を応用し、より実用的なコードを書くために重要な高度な概念便利な機能をいくつかご紹介します。


16. デリゲート(Delegate)とイベント(Event)

これらは、メソッドを変数として扱うための機能で、特にイベント処理やコールバック処理の設計に不可欠です。

📌 デリゲート(Delegate)

デリゲートは、メソッドへの参照(ポインター)を保持する型です。これにより、メソッドを引数として渡したり、変数に格納したりできるようになります。

C#

// 1. デリゲートの定義(どんなメソッドを格納できるかの「型」を定義)
// 戻り値がintで、引数がint二つのメソッドを指せる
public delegate int CalculationDelegate(int x, int y);

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Subtract(int a, int b) => a - b;
}

// 2. デリゲート変数にメソッドを割り当てる
Calculator calc = new Calculator();
CalculationDelegate del = calc.Add; // Addメソッドを代入

// 3. デリゲートを通じてメソッドを呼び出す
int result = del(10, 5); // 実際にはcalc.Add(10, 5)が実行される
System.Console.WriteLine($"結果: {result}"); // 出力: 15

📢 イベント(Event)

イベントは、デリゲートを利用して実装される、特定の出来事(イベント)の発生を通知するための仕組みです。ボタンクリックなど、UIプログラミングで頻繁に使われます。

イベントの購読者(通知を受け取る側)は、イベントが発生した際に実行するメソッドを登録(購読)します。

C#

// 1. イベントを発行する側(Publisher)
public class Button
{
    // イベント発生時のデリゲートを定義
    public event EventHandler Click;

    public void OnClick()
    {
        // イベントを購読しているメソッドがあれば呼び出す
        Click?.Invoke(this, EventArgs.Empty);
    }
}

// 2. イベントを処理する側(Subscriber)
public class MainWindow
{
    public MainWindow()
    {
        Button button = new Button();
        // イベントに処理メソッドを登録(購読)
        button.Click += Button_Clicked; 

        // イベントの発生(ボタンが押された)
        button.OnClick();
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        System.Console.WriteLine("ボタンがクリックされました!");
    }
}

17. 拡張メソッド(Extension Method)

既存のクラス(例えば、C#標準の stringList<T> など)のソースコードを変更することなく、後からメソッドを追加できる便利な機能です。

⚙️ 定義と使用方法

拡張メソッドは、以下の条件を満たした静的(static)クラス内の静的メソッドとして定義します。

  1. クラスとメソッドの両方に static を付ける。
  2. メソッドの第1引数this キーワードを付け、拡張したい型を指定する。

C#

// 1. 拡張メソッドを定義するための静的クラス
public static class StringExtensions
{
    // string型を拡張するメソッドを定義
    public static string ToCapitalized(this string s) // this string s が重要
    {
        if (string.IsNullOrEmpty(s)) return s;
        // 最初の文字を大文字、それ以降を小文字に変換
        return char.ToUpper(s[0]) + s.Substring(1).ToLower();
    }
}

// 2. 拡張メソッドの使用
string name = "apple";
// 既存のstring型のメソッドのように呼び出せる
string capitalizedName = name.ToCapitalized();

System.Console.WriteLine(capitalizedName); // 出力: Apple

拡張メソッドは、System.LinqWhere(), Select() など、LINQのメソッド群にも多用されており、非常に役立つ機能です。


18. Null許容型(Nullable Types)

C#の値型(int, bool, DateTimeなど)は、通常 null(値がない状態)を取ることができません。しかし、データベースのフィールドのように「値がない」状態を表現したい場合があります。

? 記号を型に付けることで、その値型が null を保持できるようになります。

❓ 定義とチェック

C#

// Null許容な整数型
int? nullableInt = null;

// Null許容な日付型
DateTime? nullableDate = new DateTime(2025, 1, 1);

// 値を代入する
nullableInt = 100;

// nullかどうかをチェックする
if (nullableInt.HasValue) // 値を持っているか確認
{
    // HasValueがTrueの場合、Valueプロパティで値を取り出す
    System.Console.WriteLine($"値があります: {nullableInt.Value}");
}
else
{
    System.Console.WriteLine("値はnullです。");
}

🚪 null合体演算子 (??)

Null許容型が null の場合に、代わりに使うデフォルト値を簡単に指定するための演算子です。

C#

int? nullableScore = null;

// nullableScoreがnullなら、代わりに 0 を使う
int score = nullableScore ?? 0;

System.Console.WriteLine($"スコア: {score}"); // 出力: 0

これで、C#の基礎から応用まで、包括的な知識が身につきました。これらの概念を組み合わせることで、多様なアプリケーション開発に挑戦できるようになります。頑張ってください!