Question

J'utilise int à titre d'exemple, mais cela s'applique à tout type de valeur dans .Net

Dans .Net 1, ce qui suit lève une exception de compilateur:

int i = SomeFunctionThatReturnsInt();

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

Maintenant (en .Net 2 ou 3.5) cette exception a disparu.

Je sais pourquoi c'est:

int? j = null; //nullable int

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

Le problème est que parce que int? est nullable et que i == null a désormais une conversion implicite vers null. La syntaxe ci-dessus est la magie du compilateur. Vraiment nous faisons:

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)

Alors maintenant, quand nous faisons <=> nous obtenons:

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

Etant donné que C # est en train de faire la logique du compilateur pour calculer cela de toute façon, pourquoi ne peut-il pas être assez intelligent pour ne pas le faire lorsqu'il s'agit de valeurs absolues comme <=>?

Était-ce utile?

La solution

Je ne pense pas qu'il s'agisse d'un problème de compilation en soi ; une valeur entière n'est jamais nulle, mais l'idée de les assimiler n'est pas invalide; c'est une fonction valide qui retourne toujours false. Et le compilateur sait; le code

bool oneIsNull = 1 == null;

compile, mais donne un avertissement au compilateur: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'.

Donc, si vous souhaitez que l'erreur du compilateur soit corrigée, accédez aux propriétés du projet et activez l'option "Traiter les avertissements comme des erreurs" pour cette erreur. Vous commencerez à les voir à nouveau comme des problèmes de construction.

Autres conseils

Bizarre ... compiler ceci avec VS2008, en ciblant .NET 3.5:

static int F()
{
    return 42;
}

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

    if (i == null)
    {
    }
}

Je reçois un avertissement du compilateur

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

Et il génère l'IL suivant ... qui, vraisemblablement, optimise le JIT

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

Pouvez-vous poster un extrait de code?

Le compilateur continue de générer un avertissement lorsque vous comparez le type non nullable à null, ce qui est exactement ce qu'il devrait être. Votre niveau d'avertissement est peut-être trop bas ou cela a été modifié dans les versions récentes (je ne l'avais fait que dans .net 3.5).

Le framework 2.0 a introduit le type de valeur nullable. Même si la constante littérale & "; 1 &"; ne peut jamais être null, son type sous-jacent (int) peut maintenant être converti en un type Nullable int. Je suppose que le compilateur ne peut plus supposer que les types int ne sont pas nullables, même s'il s'agit d'une constante littérale. Je reçois un avertissement lors de la compilation 2.0:

Avertissement 1 Le résultat de l'expression est toujours 'faux' car une valeur de type 'int' n'est jamais égale à 'null' de type 'int?'

L’avertissement est nouveau (3.5 je pense) - l’erreur est la même que si j’avais fait 1 == 2, qu’il est assez intelligent pour déceler comme jamais vrai.

Je pense qu'avec les optimisations 3.5 complètes, toute la déclaration sera supprimée, car elle est plutôt intelligente avec des évaluations jamais vraies.

Bien que je puisse vouloir 1==2 compiler (pour désactiver un bloc de fonction pendant que je teste autre chose, par exemple), je ne veux pas 1==null.

Il devrait s'agir d'une erreur de compilation, car les types sont incompatibles (les types de valeur ne peuvent jamais être nuls). C'est assez triste que ce ne soit pas le cas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top