反変性

さらに難しいのが反変性。

共変性と反変性 (C#) | Microsoft Docs
デリゲート - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

引数が派生クラスの関数、引数が基底クラスの関数があった時、派生クラスを受け取る関数のデリゲートに、基底クラスを受け取る関数を入れることが出来る。

BaseClass.csは、

DerivedClass.csは、

MainClass.csは、最初は、

// 名前空間の登録
using System;   // 共通データ型と基本クラス(System名前空間)

// デリゲートの宣言
delegate void DelegateSetDerived(DerivedClass dc);  // DerivedClassをセットするデリゲート.

// メインクラス
class MainClass // MainClassの定義
{

    // メインメソッド
    static void Main()  // Mainメソッドの定義
    {

        // デリゲートの初期化.
        DelegateSetDerived dsd = null;  // dsdをnullで初期化.

        // デリゲートに派生クラスをセットするメソッドを追加.
        dsd += new DelegateSetDerived(SetDerived);  // dsdにSetDerivedを追加.

        // 追加したことを出力.
        Console.WriteLine("Add SetDerived to dsd!");    // "Add SetDerived to dsd!"と出力.

        // DerivedClassの初期化.
        DerivedClass dc = new DerivedClass();   // DerivedClassオブジェクトdcを生成.
        dc.Name = "Jiro";   // dc.Nameに"Jiro"をセット.
        dc.Address = "Osaka";   // dc.Addressに"Osaka"をセット.

        // dcをdsdに渡す.
        dsd(dc);    // dsdにdcを渡す.

        // さきほどのメソッドを除去.
        dsd -= SetDerived;  // dsdからSetDerivedを削除.

        // デリゲートに基底クラスをセットするメソッドを追加.
        dsd += new DelegateSetDerived(SetBase);  // dsdにSetBaseを追加.

        // 追加したことを出力.
        Console.WriteLine("Add SetBase to dsd!");   // "Add SetBase to dsd!"と出力.

        // BaseClassの初期化.
        BaseClass bc = new BaseClass(); // BaseClassオブジェクトbcを作成.
        bc.Name = "Taro";   // ここでは"Taro"をセット.

        // bcをdsdに渡す.
        dsd(bc);    // dsdにbcを渡す.

    }

    // DerivedClassオブジェクトをセットするメソッド.
    static void SetDerived(DerivedClass dc)
    {

        // dcを受け取ったことを出力.
        Console.WriteLine("Set DerivedClass Object!");  // "Set DerivedClass Object!"と出力.

        // メンバの出力.
        Console.WriteLine("dc.Name = " + dc.Name);  // dc.Nameを出力.
        Console.WriteLine("dc.Address = " + dc.Address);    // dc.Addressを出力.

    }

    // BaseClassオブジェクトをセットするメソッド.
    static void SetBase(BaseClass bc)
    {

        // bcを受け取ったことを出力.
        Console.WriteLine("Set BaseClass Object!"); // "Set BaseClass Object!"と出力.

        // メンバの出力.
        Console.WriteLine("bc.Name = " + bc.Name);  // bc.Nameを出力

    }

}

こういう風にしてみたが、

エラー
エラー

デリゲート型が派生なので、やっぱ基底で渡すのはダメみたいで、

とする。
(入れられる関数が基底でもいいだけで、セットするクラスは派生でないといけない。)

成功
成功

通った。

Add SetDerived to dsd!
Set DerivedClass Object!
dc.Name = Jiro
dc.Address = Osaka
Add SetBase to dsd!
Set BaseClass Object!
bc.Name = Taro
続行するには何かキーを押してください . . .

関数は基底が呼ばれている。

Sample/cs/Contravariance/Contravariance/src/Contravariance at master · bg1bgst333/Sample · GitHub