Mise à JOUR: Cette question a été l'objet de mon blog en juillet 2013. Merci pour la grande question!
J. Kommer réponse est bonne (et bien sur pour ce qui est de toute évidence beaucoup de spec à creuser!) mais je pensais ajouter un peu de perspective historique.
Lorsque Mads et j'ai été tri de la formulation exacte des diverses parties de la spécification de C# 3.0, nous nous sommes rendu compte que le "null" type était bizarre. C'est un "type" avec une seule valeur. C'est un "type" que la Réflexion ne sait rien. C'est un "type" qui n'ont pas de nom, que GetType ne retourne jamais, que vous ne pouvez pas spécifier le type d'une variable locale ou un champ ou quoi que ce soit. En bref, c'est vraiment un "type" qui est là uniquement pour rendre le système de type "complète", de sorte que chaque moment de la compilation de l'expression a un type.
Sauf que C# déjà eu des expressions qui n'avaient aucun type: méthode des groupes en C# 1.0, les méthodes anonymes en C# 2.0 et les lambdas en C# 3.0 n'ont pas du tout le type. Si toutes ces choses ne peut avoir aucun type, nous avons réalisé que "null" n'ont pas besoin d'un type ou l'autre. Par conséquent, nous avons supprimé les références à l'inutile "de type null" en C# 3.0.
Comme un détail d'implémentation, les implémentations de Microsoft C# 1.0 à 5.0 toutes ont un objet interne pour représenter le "type null". Ils ont aussi des objets pour représenter les non-existant types de lambdas, les méthodes anonymes et de la méthode des groupes. Cette mise en œuvre, le choix a un certain nombre des avantages et des inconvénients. Sur le coté pro, le compilateur peut demander le type d'une expression et d'obtenir une réponse. Sur la con côté, cela signifie que parfois, des bugs dans le type d'analyse qui devraient avoir écrasé le compilateur au lieu de provoquer des changements sémantiques dans les programmes. Mon exemple préféré est qu'il est possible en C# 2.0 pour utiliser l'expression illégale "null ?? null"; à cause d'un bug du compilateur ne parvient pas à le signaler comme étant une utilisation erronée de l' ??
de l'opérateur, et continue d'en déduire que le type de cette expression est "le type null", même si ce n'est pas un null littérale. Qui va ensuite à cause de beaucoup d'autres en aval de bugs comme le type de l'analyseur tente de faire sens de ce type.
Dans Roslyn nous ne sera probablement pas utiliser cette stratégie; au contraire, nous allons tout simplement faire cuire dans le compilateur de mise en œuvre que quelques-unes des expressions non pas de type.