Esta questão foi o assunto do meu blog em 30 de maio de 2013 . Obrigado pela ótima pergunta!
Você está olhando para uma entrada de automóveis vazia.
Alguém pergunta a você "sua entrada de automóveis pode segurar um Honda Civic?"
Sim. Sim pode.
Alguém aponta você para uma segunda entrada. Também está vazio. Eles perguntam "O conteúdo atual da minha entrada pode se encaixar na sua entrada?"
Sim, obviamente. Ambas as entradas estão vazias! Então, claramente, o conteúdo de um pode caber no outro, porque também não há conteúdo.
Alguém lhe pergunta "A sua entrada de automóveis contém um Honda Civic?"
Não, não tem.
Você está pensando que o isoperador responde à segunda pergunta: dado esse valor, ele se encaixa em uma variável desse tipo? Uma referência nula se encaixa em uma variável desse tipo? Sim.
Essa não é a pergunta que o isoperador responde. A pergunta que o isoperador responde é a terceira pergunta. y is Xnão pergunta " é yum valor legal de uma variável do tipo X? ", pergunta " É yuma referência válida para um objeto do tipo X? " Como uma referência nula não é uma referência válida para qualquer objeto de qualquer tipo, a resposta é "não " Aquela entrada está vazia; não contém um Honda Civic.
Outra maneira de ver isso é que y is Xresponde à pergunta "se eu dissesse y as X, obteria um resultado não nulo? Se y for nulo, claramente a resposta é não!
Para analisar um pouco mais a fundo sua pergunta:
Espera-se que o valor nulo pertença a qualquer tipo de referência (ou anulável)
Alguém poderia assumir implicitamente que um tipo é um conjunto de valores e que a compatibilidade da atribuição de um valor y com uma variável do tipo X não é nada mais nem menos do que verificar se y é um membro do conjunto x .
Embora essa seja uma maneira extremamente comum de ver tipos, essa não é a única maneira de ver tipos, e não é a maneira como o C # olha para tipos. Referências nulas são membros de nenhum tipo em C #; compatibilidade de atribuição não é apenas verificar um conjunto para ver se ele contém um valor. Só porque uma referência nula é uma atribuição compatível com uma variável do tipo de referência X não significa que nulo é um membro do tipo X. A atribuição "é compatível com" relação e a relação "é um membro do tipo" obviamente possui muitas se sobrepõem, mas não são idênticos no CLR.
Se as reflexões sobre a teoria dos tipos lhe interessam, confira meus artigos recentes sobre o assunto:
O que é isso que você chama de "tipo"? Parte um
O que é isso que você chama de "tipo"? Parte dois