2012-03-28 19 views
8

In Code unten muss ich Methode MdrResponseInterpreterstatic erklären, sonst habe ich einen Kompilierungsfehler.Warum Delegat muss statisch sein?

class.... { 

    private StandardBuilder _mdrResponseBuilder = 
     new StandardBuilder(MdrResponseInterpreter); 

    public static bool MdrResponseInterpreter(DNMessageDeliverer builder, 
               DNFieldSet message) 
    { 
     // .... work 
    } 

Warum? Als _mdrResponseBuilder nicht statisch Ich erwarte, dass MdrResponseInterpreter der Lage sein sollten this

Antwort

11

zuzugreifen Weil Feld initializers haben keinen Zugriff auf this/instance Mitglieder. Verschieben Sie die Initialisierung in den Konstruktor, wenn Sie auf Instanzmitglieder zugreifen möchten.

Die Spezifikation sagt:

Eine Variableninitialisierer für eine Instanz Feld nicht die Instanz erstellt wird, verweisen können. Somit ist es ein Fehler Kompilierung-this in einer Variableninitialisierer

Während Ihr Code verweisen ausdrücklich nicht this verweisen, die Methode Gruppenumwandlung zu delegieren referenziert this implizit, wenn die Methode eine Instanz Mitglied ist.

1

Sie dürfen keine Instanzelemente in Initialisierern verwenden.

Denken Sie an einen Delegaten als 1) Eine Objektreferenz und 2) Eine Methodenreferenz. Da Sie nicht auf this zugreifen können, gibt es keine Möglichkeit, den Objektreferenz festzulegen, so die einzige Möglichkeit, die Methode als einen Delegaten verwenden können, ist es als static zu deklarieren (weil die Objektverweis eines Delegaten null für statische Methoden ist). Wenn Sie Ihre Initialisierung in den Konstruktor verschieben, können Sie dies umgehen.

+1

Dort ist definitiv * ist * ein Objekt an diesem Punkt (wo sonst wird der Wert zugewiesen?), Aber Sie haben noch nicht Zugriff auf 'this'. –

+0

Sicher, ich war unklar. Meine Antwort wurde aktualisiert. – Botz3000

+0

Ich würde immer noch sagen, dass es unklar ist. Das Objekt * existiert * vollständig. Es wurde möglicherweise nicht vollständig * initialisiert *, aber das gilt auch für den Konstruktor. (Es kann noch andere abgeleitete Konstruktor-Körper geben, die noch laufen müssen ...) –

1

Die Methode muss statisch sein, da sie bei der Objektinitialisierung aufgerufen wird, bevor der Konstruktor gestartet wurde. Wenn Sie auf this zugreifen möchten, rufen Sie die Initialisierungsmethode in Ihrem Konstruktor auf.

5

zu CodeInChaos Antwort hinzuzufügen (was richtig ist), können Sie nur die Zuordnung zu dem Konstruktor verschieben:

private StandartBuilder _mdrResponsBuilder; 

public Foo() // Whatever your type is called 
{ 
    // Simpler syntax for creating a delegate, too. Just use a 
    // method group conversion... 
    _mdrResponsBuilder = MdrResponseInterpreter; 
} 

EDIT: Die oben geht davon aus, dass StandartBuilder eine Art delegieren ist. Wenn es sich um einen Typ mit einem Konstruktor handelt, der einen Delegattyp akzeptiert, müssen Sie zu new StandartBuilder(MdrResponseInterpreter) zurückkehren, aber es immer noch in dem Konstruktor haben.

+0

@Downvoter: Interessieren Sie sich für einen Kommentar? –

+0

Ich frage mich nur, wie ist das "_mdrResponsBuilder = MdrResponseInterpreter" korrekt? Nichts in der Frage zeigt an, dass StandardBuilder ein Delegat ist ... Es könnte eine Klasse sein, die einen Func in ihrem Konstruktor akzeptiert? Btw, ich habe nicht downward – odalet

+1

@odalet: Ja, das ist möglich. Ich denke, es ist wahrscheinlicher (angesichts des Fragetitels), dass es sich um einen Delegattyp handelt. Wird bearbeiten, um zu klären. –

Verwandte Themen