2012-03-28 13 views
8

Nel codice seguente devo dichiarare il metodo MdrResponseInterpreterstatic altrimenti ho errore di compilazione.perché il delegato deve essere statico?

class.... { 

    private StandardBuilder _mdrResponseBuilder = 
     new StandardBuilder(MdrResponseInterpreter); 

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

Perché? Come _mdrResponseBuilder non è statica Mi aspetto che MdrResponseInterpreter dovrebbe essere in grado di accedere this

risposta

11

Perché inizializzatori dei campi non hanno accesso a this membri/istanza. Sposta l'inizializzazione al costruttore se vuoi accedere ai membri di istanza.

le specifiche dice:

Un inizializzazione variabile per un campo di istanza non può fare riferimento l'istanza in fase di creazione. Quindi, si tratta di un errore di compilazione fare riferimento this in un inizializzatore di variabile

Mentre il codice non fa riferimento in modo esplicito this, il gruppo metodo per delegare la conversione non riferimento this implicitamente se il metodo è un membro di istanza.

1

Non è consentito utilizzare i membri di istanza negli inizializzatori.

Pensare a un delegato come se avesse 1) Un riferimento a un oggetto e 2) Un riferimento al metodo. Poiché non è possibile accedere a this, non è possibile impostare il riferimento all'oggetto, pertanto l'unico modo per poter utilizzare il metodo come delegato è dichiararlo come static (poiché il riferimento dell'oggetto delegato è null per i metodi statici). Spostare l'inizializzazione nel costruttore può aiutarti a risolvere questo problema.

+1

Esiste sicuramente * un * oggetto in quel punto (altrimenti dove viene assegnato il valore?) Ma non ti è permesso accedere ancora a questo. –

+0

Certo, non ero chiaro. Aggiornato la mia risposta. – Botz3000

+0

Continuo a dire che non è chiaro. L'oggetto * esiste * completamente. Potrebbe non essere stato completamente * inizializzato *, ma è vero anche nel corpo del costruttore. (Potrebbero esserci altri corpi di costruttori derivati ​​che devono ancora essere eseguiti, anche ...) –

1

Il metodo deve essere statico perché invocato all'inizializzazione dell'oggetto, prima che il costruttore abbia iniziato l'esecuzione. Se vuoi accedere a this, chiama il metodo di inizializzazione dal tuo costruttore.

5

Per aggiungere alla risposta di CodeInChaos (che è corretto) si può semplicemente spostare l'assegnazione al costruttore:

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: È possibile che questo presuppone che StandartBuilder è un tipo delegato. Se si tratta di un tipo con un costruttore che accetta un tipo di delegato, sarà necessario tornare a new StandartBuilder(MdrResponseInterpreter), ma conservarlo nel costruttore.

+0

@Downvoter: cura di commentare? –

+0

Mi chiedo, come mai "_mdrResponsBuilder = MdrResponseInterpreter" è corretto? Nulla nella domanda indica che StandardBuilder è un delegato ... Potrebbe essere una classe che accetta Func nel suo costruttore? A proposito, non ho fatto downvote – odalet

+1

@odalet: Sì, è possibile. Penso che sia più probabile (dato il titolo della domanda) che si tratti di un tipo delegato. Modificherà per chiarire. –

Problemi correlati