Pergunta

estou a usar int como exemplo, mas isso se aplica a qualquer tipo de valor em .Net

No .Net 1, o seguinte geraria uma exceção do compilador:

int i = SomeFunctionThatReturnsInt();

if( i == null ) //compiler exception here

Agora (no .Net 2 ou 3.5) essa exceção desapareceu.

Eu sei por que isso acontece:

int? j = null; //nullable int

if( i == j )   //this shouldn't throw an exception

O problema é que porque int? é anulável e int agora tem uma conversão implícita para int?.A sintaxe acima é mágica do compilador.Na verdade estamos fazendo:

Nullable<int> j = null; //nullable int

//compiler is smart enough to do this
if( (Nullable<int>) i == j)   

//and not this
if( i == (int) j)

Então agora, quando fazemos i == null Nós temos:

if( (Nullable<int>) i == null )

Dado que o C# está fazendo a lógica do compilador para calcular isso de qualquer maneira, por que não pode ser inteligente o suficiente para não fazê-lo ao lidar com valores absolutos como null?

Foi útil?

Solução

Eu não acho que isso seja um problema do compilador por si só;um valor inteiro nunca é nulo, mas a ideia de igualá-los não é inválida;é uma função válida que sempre retorna falso.E o compilador sabe;o código

bool oneIsNull = 1 == null;

compila, mas dá um aviso ao compilador: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'.

Portanto, se você quiser que o erro do compilador volte, vá para as propriedades do projeto e ative 'tratar avisos como erros' para esse erro, e você começará a vê-los como problemas de quebra de compilação novamente.

Outras dicas

Chance ...compilando isso com o VS2008, visando o .NET 3.5:

static int F()
{
    return 42;
}

static void Main(string[] args)
{
    int i = F();

    if (i == null)
    {
    }
}

Recebo um aviso do compilador

warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'

E gera o seguinte IL ...que presumivelmente o JIT irá otimizar

L_0001: call int32 ConsoleApplication1.Program::F()
L_0006: stloc.0 
L_0007: ldc.i4.0 
L_0008: ldc.i4.0 
L_0009: ceq 
L_000b: stloc.1 
L_000c: br.s L_000e

Você pode postar um trecho de código?

O compilador ainda gera um aviso quando você compara o tipo não anulável com o nulo, que é exatamente como deveria ser.Pode ser que seu nível de aviso esteja muito baixo ou tenha sido alterado em versões recentes (só fiz isso no .net 3.5).

A estrutura 2.0 introduziu o tipo de valor anulável.Mesmo que a constante literal "1" nunca possa ser nula, seu tipo subjacente (int) agora pode ser convertido em um tipo int Nullable.Meu palpite é que o compilador não pode mais assumir que os tipos int não são anuláveis, mesmo quando é uma constante literal.Recebo um aviso ao compilar o 2.0:

Aviso 1 O resultado da expressão é sempre 'false' pois um valor do tipo 'int' nunca é igual a 'null' do tipo 'int?'

O aviso é novo (3,5, eu acho) - o erro é o mesmo que se eu tivesse feito 1 == 2, o que é inteligente o suficiente para identificar como nunca sendo verdade.

Suspeito que, com otimizações completas de 3,5, toda a afirmação será simplesmente eliminada, pois é bastante inteligente com avaliações nunca verdadeiras.

Embora eu possa querer 1==2 compilar (para desligar um bloco de função enquanto testo outra coisa, por exemplo) não quero 1==null para.

Deveria ser um erro em tempo de compilação, porque os tipos são incompatíveis (os tipos de valor nunca podem ser nulos).É muito triste que não seja.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top