Domanda

sto usando int come esempio, ma questo si applica a qualsiasi tipo di valore in .Net

In .Net 1 quanto segue genererebbe un'eccezione del compilatore:

int i = SomeFunctionThatReturnsInt();

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

Ora (in .Net 2 o 3.5) quell'eccezione è scomparsa.

So perché è così:

int? j = null; //nullable int

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

Il problema è che perché int? è nullable e int ora ha un cast implicito a int?.La sintassi sopra è magia del compilatore.Stiamo davvero facendo:

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)

Quindi ora, quando lo faremo i == null noi abbiamo:

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

Dato che C# sta comunque eseguendo la logica del compilatore per calcolarlo, perché non può essere abbastanza intelligente da non farlo quando si ha a che fare con valori assoluti come null?

È stato utile?

Soluzione

Non penso che sia un problema del compilatore di per sé;un valore intero non è mai nullo, ma l'idea di equipararli non è invalida;è una funzione valida che restituisce sempre false.E il compilatore lo sa;il codice

bool oneIsNull = 1 == null;

compila, ma fornisce un avviso al compilatore: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'.

Quindi, se vuoi ripristinare l'errore del compilatore, vai alle proprietà del progetto e attiva "tratta gli avvisi come errori" per questo errore e inizierai a vederli di nuovo come problemi che compromettono la compilazione.

Altri suggerimenti

Strano ...compilandolo con VS2008, destinato a .NET 3.5:

static int F()
{
    return 42;
}

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

    if (i == null)
    {
    }
}

Ricevo un avviso del compilatore

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 genera il seguente IL...che presumibilmente la JIT ottimizzerà

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

Puoi postare uno snippet di codice?

Il compilatore genera comunque un avviso quando si confronta il tipo non nullable con null, che è proprio come dovrebbe essere.Potrebbe essere che il tuo livello di avviso sia troppo basso o che questo sia stato modificato nelle versioni recenti (l'ho fatto solo in .net 3.5).

Il framework 2.0 ha introdotto il tipo di valore nullable.Anche se la costante letterale "1" non può mai essere nulla, il tipo sottostante (int) può ora essere convertito in un tipo int Nullable.La mia ipotesi è che il compilatore non possa più presumere che i tipi int non siano nullable, anche quando si tratta di una costante letterale.Ricevo un avviso durante la compilazione 2.0:

Attenzione 1 Il risultato dell'espressione è sempre 'false' poiché un valore di tipo 'int' non è mai uguale a 'null' di tipo 'int?'

L'avviso è nuovo (3.5 credo): l'errore è lo stesso che se lo avessi fatto 1 == 2, che è abbastanza intelligente da individuare come mai vero.

Ho il sospetto che con le ottimizzazioni 3.5 complete l'intera affermazione verrà semplicemente eliminata, poiché è piuttosto intelligente con valutazioni mai vere.

Anche se potrei volerlo 1==2 compilare (per disattivare un blocco funzione mentre provo qualcos'altro, ad esempio) non voglio 1==null A.

Dovrebbe trattarsi di un errore in fase di compilazione, perché i tipi sono incompatibili (i tipi di valore non possono mai essere nulli).È piuttosto triste che non lo sia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top