3 Stimmen

Was ist die Bedeutung eines Delegaten innerhalb einer Klasse?

Ich verstehe Delegierte als eine Abkürzung für die Definition einer Klasse mit einer Methode, aber was ist die Bedeutung von bar2 unten? Es lässt sich kompilieren. Aber ich kann nicht erkennen, was eine innere Klasse hier tun würde. Ich weiß, dass ich etwas übersehe, deshalb frage ich (dies ist keine Hausaufgabe, ich bin gerade bei der Arbeit).

namespace ns2 { public delegate void bar();}
public class foo
{
    private ns2.bar _callback;
    public foo(ns2.bar callback) { _callback = callback; }
    public void baz() { _callback(); }
    public delegate void bar2();
}

Gracias.

8voto

Eric Lippert Punkte 628543

Um die Antworten von Jon und Jared zu ergänzen, möchte ich anmerken, dass man normalerweise nur dann einen Delegaten innerhalb einer Klasse definieren würde, wenn der Delegat ein privates Implementierungsdetail der Klasse wäre. Es ist selten und bizarr, einen öffentlich Delegatendefinition innerhalb einer Klasse.

Nehmen wir zum Beispiel mein Lieblingsmuster: eine abstrakte Basisklasse, die nur durch private verschachtelte Klassen erweitert werden kann, die mit Fabriken hergestellt werden:

public abstract class Animal
{
    private Animal() { } // prevents subclassing from outside!
    private sealed class Giraffe : Animal { }
    private sealed class Leopard : Animal { }
    public static Animal GetGiraffe( ) { return new Giraffe(); }
    public static Animal GetLeopard( ) { return new Leopard(); }

Angenommen, ein Implementierungsdetail von Animal besteht darin, dass Sie einen Delegaten von Giraffe zu Leopard benötigen:

    private delegate Leopard D(Giraffe g);

Dies kann keine öffentliche Delegatenklasse sein, da sie sich auf private Typen bezieht!

Heutzutage würde man so etwas natürlich nicht mehr tun. Sie würden Func<Giraffe, Leopard> und Sie sind fertig.

Daher ist der verschachtelte Delegatentyp heutzutage eher der Vollständigkeit und Abwärtskompatibilität halber vorhanden; normalerweise würde man ihn nicht verwenden.

7voto

JaredPar Punkte 699699

Delegierte sind keine Abkürzungen für die Definition einer Klasse mit einer Methode. Sie verfügen vielmehr über mindestens 6 Methoden (Invoke, BeginInvoke, EndInvoke, GetHashCode, Equals, ToString).

Ein Grund für das Muster, Delegierte innerhalb eines Typs zu platzieren, ist die Vermeidung globaler Namespace-Verschmutzung. Der Delegat bar2 ist nur über einen qualifizierten Verweis von foo . Dies kann nützlich sein, wenn bar2 ist ein Name, der mehrere gültige Bedeutungen hat, und er wird in foo liefert den notwendigen Kontext.

6voto

Jon Skeet Punkte 1325502

Es wird lediglich ein verschachtelter Typ deklariert, das ist alles. Da er öffentlich ist, gibt es so gut wie keinen Unterschied zwischen der Deklaration innerhalb des Typs und der Deklaration außerhalb.

Andere Klassen müssen über den Namen des enthaltenen Typs darauf verweisen (es sei denn, sie haben eine using Richtlinie speziell für sie):

public class OtherClass
{
    private void DoSomething()
    {
        foo.bar2 action = delegate { ... };
        foo f = new foo(action);
        ...
    }
}

Normalerweise Wenn ich einen verschachtelten Typ schreibe, ist er privat - er ist nur eine Hilfsklasse für die enthaltende Klasse; ein Implementierungsdetail. Das muss natürlich nicht der Fall sein, aber es sollte zumindest so sein, dass der verschachtelte Typ bedeutungslos ist, es sei denn, Sie sind in einige mit Hilfe der äußeren Klasse. Es könnte zum Beispiel ein Builder für die äußere Klasse sein oder ein Enum, das in einigen Parametern für einen Methodenaufruf innerhalb der äußeren Klasse verwendet wird.

(Übrigens ist es beim Schreiben von Beispielcode wie diesem nützlich, den .NET-Namenskonventionen zu folgen, selbst für metasyntaktische Namen wie Foo y Bar . So wird z. B. der Unterschied zwischen Variablen und Typen deutlicher).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X