In C#, un costruttore corre la sequenza:
Perform all field initializers
Chain to base class constructor
Execute user-supplied code for constructor
in vb.net, la sequenza è:
Chain to base class constructor
Perform all field initializers
Execute user-supplied code for constructor
Non c'è Framework-base motivo per cui C# fa le cose nell'ordine che fa, come dimostra il fatto che vb.net può e le fa in una sequenza diversa. La giustificazione del progetto per l'approccio C# è che non dovrebbe esserci alcuna possibilità che un oggetto venga esposto al mondo esterno prima che tutti gli inizializzatori di campo (per i campi derivati e di classe base) siano stati eseguiti; poiché un costruttore della classe base potrebbe esporre un oggetto al mondo esterno, l'applicazione di tale requisito implica che gli inizializzatori del campo debbano essere eseguiti prima del costruttore della classe base.
Personalmente, non trovo questa giustificazione particolarmente convincente. Esistono molti scenari in cui non sarà possibile impostare i campi su valori utili senza avere informazioni che non saranno disponibili prima dell'esecuzione del costruttore base. Qualsiasi codice il cui costruttore di base possa esporre istanze parzialmente costruite deve essere preparato per tale possibilità. Mentre ci sono momenti in cui sarebbe utile specificare che un inizializzatore di campo dovrebbe essere eseguito "in anticipo", penso che ci siano molte altre situazioni in cui è utile per loro poter accedere all'oggetto di fantasia (in qualche misura perché credo che i campi di classe i cui valori dovrebbero essere considerati come invarianti durante la vita di un'istanza di classe dovrebbero, quando è pratico, essere impostati in modo dichiarativo tramite inizializzatori piuttosto che imperativamente all'interno di un costruttore).
Per inciso, una funzione che mi piacerebbe vedere in entrambi vb.net e C# sarebbe un mezzo per dichiarare campi inizializzati da parametri e pseudo-campi. Se una classe ha un campo inizializzato con parametri di un certo nome e tipo, ogni costruttore per quella classe che non fa catena ad un altro della stessa classe deve contenere parametri con i nomi e i tipi appropriati. I valori di quei campi verrebbero impostati nel costruttore prima di ogni altra cosa e sarebbero accessibili ad altri inizializzatori di campo. Gli pseudo-campi si comporterebbero in modo sintattico come i campi, eccetto che sarebbero solo utilizzabili negli inizializzatori di campo e sarebbero implementati come variabili locali all'interno dei costruttori. Una tale caratteristica renderebbe più convenienti molti tipi di strutture. Ad esempio, se un tipo è dovuto tenere un caso particolare matrice tutta la sua durata, potendo fare:
readonly param int Length;
readonly ThingType[] myArray = new ThingType[Length];
sembrerebbe bello di dover costruire la serie sia nel costruttore della classe (che non potrebbe accadere fino a dopo l'esecuzione del costruttore base) o (per vb.net) dovendo passare la lunghezza a un costruttore di classe base che potrebbe quindi utilizzarlo per impostare un campo (che occuperebbe quindi spazio nella classe anche se il suo valore-- come Length
sopra - potrebbe essere ridondante).
No, il motivo per cui non viene compilato non è affatto che 'Identity' è nella classe base, è semplicemente perché è un membro di istanza. Quindi, la domanda nel titolo non è rilevante per quello che stai cercando di fare ... – Guffa