Perché non puoi usare “this” negli inizializzatori dei membri?

Possibile duplicato:
Non è ansible usare “this” nell’inizializzatore membro?

Qualche idea per cui ottengo un errore se provo a fare qualcosa del genere:

public class Bar { public Bar(Foo foo) { } } public class Foo { private Bar _bar = new Bar(this); } 

Ottengo un errore dicendo:

“Non posso usare” questo “nell’inizializzatore membro”

ma i seguenti lavori:

 public class Foo { private Bar _bar; public Foo() { _bar = new Bar(this); } } 

Qualcuno sa la ragione di questo? La mia comprensione era che questi sarebbero stati compilati con lo stesso IL, quindi sono curioso di sapere perché uno è permesso e l’altro no.

Grazie, Alex

Sospetto che sia per impedirti di utilizzare l’object prima che il costruttore della class base sia eseguito, assicurando che tutti i membri della class base siano inizializzati in modo appropriato. (Gli inizializzatori variabili vengono eseguiti prima del costruttore della class base, mentre successivamente viene eseguito il corpo del costruttore.)

Verificherà se le specifiche annotate hanno qualcosa da dire su questo quando sono vicino ad esso …

EDIT: Le specifiche annotate C # 4 non hanno alcuna spiegazione. Semplicemente (in 10.5.5.2):

Un inizializzatore di variabili per un campo di istanza non può fare riferimento all’istanza che si sta creando.

Gli inizializzatori di campo vengono eseguiti prima dei costruttori della class base, quindi this non esiste ancora. Esiste solo una volta che il costruttore base ha terminato l’esecuzione.

17.10.2 Iniziatori di variabili di istanza :

Quando un costruttore di istanze non ha inizializzatore di costruttore o ha un inizializzatore di costruttore del modulo base (…), tale costruttore esegue implicitamente le inizializzazioni specificate dagli inizializzatori di variabile dei campi di istanza dichiarati nella relativa class. Ciò corrisponde a una sequenza di assegnazioni che vengono eseguite immediatamente dopo l’immissione nel costruttore e prima dell’invocazione implicita del costruttore della class base diretta. Gli inizializzatori variabili vengono eseguiti nell’ordine testuale in cui appaiono nella dichiarazione della class.

Credo che questo sia dovuto al fatto che i campi vengono inizializzati prima dell’inizializzazione della class, quindi quando viene eseguito il seguente codice:

 private Bar _bar = new Bar(this); 

“questo” non ha alcun valore reale a cui fare riferimento.

Inserendolo nel costruttore significa che c’è un’istanza di “Foo” referenziabile da “questo”

Gli inizializzatori dei membri vengono eseguiti prima del costruttore della class. Considera che potresti avere molti inizializzatori di membri in una singola class.

Se si utilizza ‘this’ nel costruttore -> tutti i membri con gli inizializzatori sono stati inizializzati. Quindi tutto è OK.

Se si utilizza ‘this’ nell’inizializzatore del membro: gli altri membri (con gli inizializzatori collegati) potrebbero non essere ancora inizializzati -> ‘this’ non è ancora pronto. Questo è il motivo per cui l’uso di “questo” non è permesso qui non è permesso.

In C #, nessuna logica è destinata ad essere al di fuori dei metodi e dei corpi delle proprietà.

Gli inizializzatori di campo sono un’eccezione, ma con alcune limitazioni.

Sarebbe sbagliato ottenere un riferimento dell’object corrente con questa parola chiave perché la dichiarazione di un campo di class non è logica ma design di class, mentre questa è parte della semantica di runtime.

A proposito, sembra che sia una decisione di progettazione in C #, perché, in effetti, un inizializzatore di campo viene eseguito durante la costruzione della class, quindi “l’istanza corrente della class di dichiarazione” dovrebbe essere disponibile attraverso questo . Ma ancora, quale sarebbe questo al di fuori di un metodo o di un ambito di proprietà?

Come indicato da Jon Skeet e altri, questo non è disponibile perché gli inizializzatori dei campi vengono eseguiti dopo l’esecuzione del costruttore di base.