質問

次の質問を読んだ後、私は次の質問を読んだ後、代表団の差異を掘り下げていました。 DeLegate.CreatedElegate()およびgenerics:ターゲットへのエラーバインディング

バリー・ケリーからとても素敵なコードを見つけましたhttps://www.blogger.com/comment.g?blogid=8184237816669520763&postid=2109708553230166434

ここにあります(砂糖入りの形式:-)

using System;

namespace ConsoleApplication4
{
    internal class Base
    {
    }

    internal class Derived : Base
    {
    }

    internal delegate void baseClassDelegate(Base b);

    internal delegate void derivedClassDelegate(Derived d);


    internal class App
    {
        private static void Foo1(Base b)
        {
            Console.WriteLine("Foo 1");
        }

        private static void Foo2(Derived b)
        {
            Console.WriteLine("Foo 2");
        }

        private static T CastDelegate<T>(Delegate src)
            where T : class
        {
            return (T) (object) Delegate.CreateDelegate(
                                    typeof (T),
                                    src.Target,
                                    src.Method,
                                    true); // throw on fail
        }

        private static void Main()
        {
            baseClassDelegate a = Foo1; // works fine

            derivedClassDelegate b = Foo2; // works fine

            b = a.Invoke; // the easy way to assign delegate using variance, adds layer of indirection though

            b(new Derived());

            b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection

            b(new Derived());
        }
    }
}

私はこれを除くすべてを理解しています(非常にシンプルに見えるもの)ライン。

b = a.invoke; //分散を使用してデリゲートを割り当てる簡単な方法で、間接の層を追加しますが

誰かが私に言うことができます:

  1. 静的関数で必要なPARAMを渡さずに、呼び出すことができる方法。
  2. 呼び出しのreturn値を割り当てるときに、フードの下でいつ続くかがいつ行われますか
  3. バリーは余分な間接とはどういう意味ですか(彼のコメントで)
役に立ちましたか?

解決

彼は電話していません Invoke (の欠如に注意してください ())、彼は暗黙のデリゲートの作成を使用して設定しています b 新しいものに等しい derivedClassDelegate を指すインスタンス Invoke の方法 a. 。追加の間接は、いつです b 呼び出されます、それは呼び出します a.Invoke(new Derived()) ただではなく a(new Derived()).

実際に起こっていることをより明確にするために:

baseClassDelegate a = Foo1; // works fine 

derivedClassDelegate b = Foo2; // works fine 

b = new derivedClassDelegate(a.Invoke); // the easy way to assign delegate using variance, adds layer of indirection though 

b(new Derived());

b = CastDelegate<derivedClassDelegate>(a); // the hard way, avoids indirection 

b(new Derived());

最初の呼び出し b このようなチェーンになります(簡単にするためにパラメーターが排除されました):

b() -> a.Invoke() -> Foo1()

2番目の呼び出し b 結果:

b() -> Foo1()

でも

これは、別の(制限の少ない)署名の代表者を呼び出すために、ある署名の代表者が必要な場合にのみ必要です。彼の例では、設定することができます b = Foo1 コンパイルされますが、それはポイントを説明しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top