Frage

ich tat einige Gräben um in Delegaten Varianz nach den folgenden Fragen in SO lesen: Delegate.CreateDelegate () und Generika: Fehler zu Zielmethode Bindung

fand ich ein sehr schönes Stück Code von Barry Kelly auf https://www.blogger.com/comment.g?blogID=8184237816669520763&postID= 2109708553230166434

Hier ist es (in einer gezuckerten-up Form: -)

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());
        }
    }
}

Ich verstehe die ganze es außer diesem (was sehr einfach aussieht) Linie.

b = a.Invoke; // Der einfache Weg zu assign delegieren Varianz, fügt Schicht Indirektionsebene obwohl

Kann mir jemand sagen Sie mir:

  1. , wie es möglich ist, zu nennen aufrufen, ohne den param durch die statische Funktion erforderlich vorbei.
  2. Wenn unter der Haube geht, wenn Sie den Rückgabewert zuweisen aus aufrufen invoke
  3. Was bedeutet Barry durch zusätzliche Indirektion (in seinem Kommentar)
War es hilfreich?

Lösung

Er ist nicht Invoke Aufruf (man beachte das Fehlen von ()), er mit impliziten Delegierten Schöpfung Satz b gleich zu einem neuen derivedClassDelegate Beispiel, dass Punkte auf die Invoke Methode von a. Die zusätzliche Indirektion ist, dass, wenn b aufgerufen wird, ruft er a.Invoke(new Derived()) nicht nur a(new Derived()).

zu machen, was eigentlich los ist deutlicher:

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());

Der erste Aufruf von b Ergebnisse in einer Kette wie folgt aus (Parameter der Einfachheit halber weggelassen):

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

Der zweite Aufruf von b ergibt dies:

b() -> Foo1()

Doch

Dies ist nur erforderlich, wenn Sie einen Vertreter eine Unterschrift benötigen einen Delegierten eines anderen (weniger restriktive) Unterschrift aufzurufen. In seinem Beispiel könnten Sie nur Satz b = Foo1 und es wäre kompilieren, aber das würde nicht den Punkt darstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top