10
votes

Quelle est la différence entre "foo = rien" et "foo n'est rien" dans vb.net?

in vb.net , quelle est la différence entre xxx

et xxx


mise à jour J'ai reçu la réponse suivante:

foo n'est rien simplement vérifie si foo n'est attribué à aucune référence. foo = rien vérifie si la référence détenue par foo est égale à rien .

Après avoir exécuté les trois instructions, xxx

foo est rien évalue sur false et foo = rien évalue en true.

Cependant, si bar est déclaré comme un objet objet et non initialisé, puis foo n'est rien et foo = rien évaluate à vrai! Je pense que c'est parce que integer est un type de valeur et objet est un type de référence.


0 commentaires

6 Réponses :


3
votes
foo is Nothing simply checks if `foo` is not assigned to any reference.

foo=Nothing checks if the reference held by `foo` is equal to `nothing`
In VB, both statements will evaluate to the same value if foo has not been initialised

3 commentaires

Et si FOO n'est pas un type de référence? Ou si foo est une corde? Êtes-vous sûr qu'il évaluera à la même valeur?


Les types de valeur entrent en jeu lorsque la méthode est générique, mais pour une chaîne vierge (c.-à-d. »), Puis produira des résultats différents.


@Lasse, voyez ma réponse pour quand FOO est nullable (de t).



2
votes

Voici quelques IL pour valider les différences:

Sub Main()
        Dim o As New Object

        If o Is Nothing Then
            Console.WriteLine("Is Nothing")
        End If

        If o = Nothing Then
            Console.WriteLine("Is nothing")
        End If
    End Sub


2 commentaires

Essayez également ceci avec une chaîne ne contenant rien, une chaîne contenant "" et un type de valeur, disent un entier et utilisez la valeur par défaut pour le type de valeur et autre chose, à savoir. Laissez-le à 0, puis vérifiez-en 1 aussi.


@Lasse - Je n'ai pas le temps d'ajouter plus d'exemples que j'ai peur. Peut-être que quelqu'un d'autre peut faire cela pour référence?



1
votes

FOO est un pointeur à un emplacement de mémoire et rien signifie "ne pas pointer vers une mémoire car aucune mémoire n'a été allouée". Equals signifie que lorsque vous comparez 2 types de valeur, ils ont la même valeur. Mais vous supposez que FOO représente un objet, qui est toujours un type de référence destiné à pointer vers un objet en mémoire. 'est' est de comparer les types d'objets et ne reviendra que «vrai» si vous avez deux objets pointant sur la même valeur.

Dites que vous avez CLSFOO avec une variable d'élément entier public «X» et FOO1 et FOO2 sont à la fois CLSFOO et Y et Z sont des entiers xxx

jamais < / Fort> oublier de transformer les options strictes. Pour échouer, il s'agit de crier 's'il vous plaît rendre mon programme sucer.'


2 commentaires

Il semble que vous ayez oublié des structures nullables oubliables, qui devraient utiliser n'est rien au lieu de = rien .


La question de l'OP ne prouve pas exactement de tels détails, à moins qu'il ne le posait comme un concours ;-)



11
votes

Cela dépend du type.

  • pour Types de valeur , est ne fonctionne pas , uniquement = et Rien fait référence à l'instance par défaut de ce type (c'est-à-dire l'instance que vous obtenez en appelant nouveau t () pour un type donné t ).

  • pour Types de référence , est exécute une comparaison de référence (identique à objet.reeferequensize (A, rien) ). a = rien généralement ne fonctionne pas , sauf si opérateur = a été défini explicitement pour cette classe.

    Si, en outre, opérateur = a été implémenté correctement, alors foo = rien et foo n'est rien devrait donner le même résultat (mais Il en va de même pour toute autre valeur au lieu de rien ) mais foo est rien sera plus efficace car c'est un compilateur intrinsèque tandis que opérateur = appellera une méthode.

  • pour types de valeur nullables (c.-à-d. des instances de nullable (de t) ), des règles spéciales s'appliquent: Comme tous les autres opérateurs, = est levé < / EM> (remarquez l'erreur dans ce poteau de blog ...) par le compilateur au type sous-jacent. Le résultat de la comparaison de deux nullable S n'est donc pas booléen mais booléen? (notez le ? ). Cependant, en raison de la soi-disant "propagation nul" pour les opérateurs soulevés, ce toujours retour rien , quelle que soit la valeur de foo . Citant le Visual Basic Spécification de langue (§1.86.3):

    Si l'opérande d'éther (sic!) est rien , le résultat de l'expression est une valeur de rien saisi en tant que version nullable du type de résultat.

    Donc, si les utilisateurs veulent comparer un NULLLABLE variable sur rien , ils doivent utiliser le foo n'est rien Syntaxe pour lequel, encore une fois , le compilateur génère un code spécial pour le faire fonctionner (§1.79.3 de la spécification de langue Visual Basic 10). Hat Tip à Jonathan Allen pour (correctement) persistant que j'avais tort; Conseil de chapeau à Jared Parsons pour me passer un lien vers la spécification Visual Basic 10.

    (ce qui précède suppose que d'option strict sur est utilisé, comme vous le toujours devriez. Si ce n'est pas le cas, les résultats diffèrent légèrement depuis l'appelant < code> foo = rien peut effectuer un appel à bornes tardif.)


10 commentaires

Pour les chaînes = et produit des résultats différents, je Daesay = est mis en œuvre avec le principe de la moins surprise pour les cordes, donc je le juge correct.


@Lasse: Oui, les chaînes sont un cas spécial dans VB depuis = appellera une méthode spéciale au lieu de égale , qui traitera rien égal à la chaîne vide.


Vous avez oublié nullable (de t). Pour ce foo = rien compilera, mais cela donne la mauvaise réponse.


@Jonathan: nullable (de t) est un type de valeur et ma réponse s'applique toujours. foo = rien sera donner la bonne réponse, et c'est équivalent à pas foo.hasvalue .


@Konrad. Ensuite, dites-moi pourquoi VB 10 nous donne le compilateur suivant Wanring. Cette expression évaluera toujours à rien (en raison de la propagation nulle de l'opérateur égal). Pour vérifier si la valeur est NULL envisager d'utiliser 'n'est rien'.


@Jonathan: Si vous pouvez me donner le code exact ... Pour le moment, le message n'a pas beaucoup de sens.


Il suffit d'utiliser ces lignes Dim FOO comme entier? = Rien et si foo = rien que


@Jonathan: C'est sans rapport. Le compilateur avertit ici parce que le si est redondant: bien sûr foo sera toujours rien , car il a été initialisé de cette façon et n'a jamais été changé. Le compilateur est assez intelligent pour comprendre que cela n'a rien à voir avec la comparabilité des types nullables. Si vous ne me croyez pas, essayez simplement Dim FOO comme entier? = 1 ou DIM FOO comme entier? = Si (nouveau aléatoire (). Nextdouble () <0.5, 1, ctype (rien, entier (rien, entier?)) - qui simule une monnaie de monnaie afin que le compilateur ne puisse pas deviner la valeur de foo < / code>.


Si vous utilisez Dim FOO comme entier? = 1 , vous obtenez le même message d'erreur. Heck, si vous faites FOO un paramètre, vous obtenez toujours le même message d'erreur. Essayez le code dans vs 2008 ou vs 2010, vous n'obtiendrez pas la même réponse que lorsque vous utilisez foo n'est rien .


@Jonathan: Je concède la défaite. La référence linguistique VB est obsolète et incomplète, et elle ne mentionne pas nullable du tout (uniquement comme une exception à la structure contrainte générique). Cela ne spécifie pas son comportement en comparaison, mais le compilateur comprend clairement certaines transformations de = , comme pour tout autre opérateur (et que vous avez correctement mentionné NULL Propagation).



1
votes

Asume:

myfunc (foo comme objet) p> BlockQuote>

FOO - Boxed si ValueType P>

Si FOO n'est rien alors P>

objet.reeferefeuls (code inlined - méthode la plus rapide) p> blockQuote>

si foo = rien que p>

opérateurs.conitionnementalCompareObjectqual (foo, rien, faux) p> BlockQuote>

vb.net Portez ce cas comme obj1 = obj2. Il n'utilise pas obj.equals (obj2)! Exception si obj1 n'est rien p>

Cette option utilise un code très complexe car il y a beaucoup d'options en fonction de toutes les définitions FOO possibles. P>

Essayez ceci: P>

Sub Main()
  Dim o As Object = 0
  Debug.Print(o Is Nothing)  'False
  Debug.Print(o = Nothing)   'True 
End Sub


0 commentaires

1
votes

Cela dépend du type de FOO.

Types de référence strong> p> xxx pré>

Types de valeur strong> p> p> XXX PRE>

NULLLABLE TYPES DE VALEUR FORT> P>

if foo = Nothing then 'This always evaluates to false. In VB 10, this is a compiler warning
if foo Is Nothing then 'Evaluates to True is foo.HasValue = False


0 commentaires