AGGIORNAMENTO: This question was the subject of my blog in July 2013. Grazie per l'ottima domanda!
risposta di J.Kommer è corretta (e bene su di loro per fare quello che era evidentemente un sacco di spec scavo!), Ma ho pensato di aggiungere un po 'di prospettiva storica.
Quando Mads ed io stavamo selezionando la formulazione esatta di varie parti della specifica per C# 3.0 ci siamo resi conto che il "tipo nullo" era bizzarro. È un "tipo" con un solo valore. È un "tipo" di cui Reflection non sa nulla. È un "tipo" che non ha un nome, che GetType non restituisce mai, che non è possibile specificare come tipo di una variabile o campo locale o altro.In breve, è davvero un "tipo" che serve solo a rendere il sistema di tipi "completo", in modo che ogni espressione in fase di compilazione abbia un tipo.
Tranne che C# aveva già espressioni prive di tipo: i gruppi di metodi in C# 1.0, i metodi anonimi in C# 2.0 e lambdas in C# 3.0 non hanno alcun tipo. Se tutte queste cose non possono avere alcun tipo, ci siamo resi conto che "null" non ha bisogno nemmeno di un tipo. Pertanto abbiamo rimosso i riferimenti al "tipo nullo" inutile in C# 3.0.
Come dettaglio di implementazione, le implementazioni Microsoft da C# 1.0 a 5.0 hanno tutti un oggetto interno per rappresentare il "tipo nullo". Hanno anche oggetti per rappresentare i tipi non esistenti di lambda, metodi anonimi e gruppi di metodi. Questa scelta di implementazione ha una serie di vantaggi e svantaggi. Dal lato pro, il compilatore può chiedere il tipo di qualsiasi espressione e ottenere una risposta. Da parte sua, ciò significa che a volte i bug nell'analisi del tipo che dovrebbero davvero aver bloccato il compilatore causano invece cambiamenti semantici nei programmi. Il mio esempio preferito è che in C# 2.0 è possibile utilizzare l'espressione illegale "null ?? null"; a causa di un bug, il compilatore non riesce a contrassegnarlo come un uso errato dell'operatore ??
e continua a dedurre che il tipo di questa espressione è "il tipo nullo", anche se non è un valore letterale nullo. Che poi continua a causare molti altri bug a valle mentre l'analizzatore di tipo cerca di dare un senso al tipo.
In Roslyn probabilmente non useremo questa strategia; piuttosto, semplicemente introdurremo nell'implementazione del compilatore che alcune espressioni non hanno alcun tipo.
fonte
2011-11-21 16:50:08
Non descriverei esattamente null avendo un tipo. – ChaosPandion
@ChaosPandion: così, in C# non l'espressione _every_ ha un tipo? – Vlad
Beh, io sono apparentemente sbagliato. – ChaosPandion