web-dev-qa-db-fra.com

Null (en C #) vs rien (en vb.net)

En quoi C # NULL est-il différent de vb.net Nothing?

Console.WriteLine(Nothing = "") => True

contre

Console.WriteLine(null==""); => False

D'après ce que j'avais compris, null et Nothing sont identiques. Mais le code ci-dessus explique clairement qu'il n'en est rien. 

Quel est l'équivalent de C # null dans VB.NET?

11
Reddy

Dans votre code, VB suppose que vous comparez Strings, car l'un des opérandes est un String. Dans les comparaisons String, Nothing est équivalent à String"" vide. Il effectue ensuite une comparaison de valeur, qui renvoie True.

Utilisez Is pour comparer les références:

Console.WriteLine(Nothing Is "") '=> False
11
SSS

Vous avez choisi l'exemple peu compliqué pour tester la différence entre Nothing dans vb.net et null en c #.

A partir de la spécification du langage Visual Basic à propos de Nothing

Rien n'est un littéral spécial; il n'a pas de type et est convertible en tous les types dans le système de types, y compris le type paramètres. Lorsqu'il est converti en un type particulier, c'est le équivalent de la valeur par défaut de ce type.

Si vous lisez la description de expressions de valeur par défaut dans la documentation Microsoft, vous remarquerez que Nothing dans vb.net et default(T) en C # ont un comportement similaire.

Par exemple

Dim isSomething As Boolean = Nothing ' = False
Dim amount As Integer = Nothing ' = 0
Dim value As String = Nothing ' = null (notice not empty string!)

Comme le prouve que la valeur par défaut de chaîne n'est pas une chaîne vide, de nombreux commentaires/réponses restent ici

Dim value As String = Nothing
If value.Equals("") Then ' will throw NullReferenceException

End If 

Comparer Nothing à la chaîne vide "" avec l'opérateur "=" est un cas spécial pour vb.net, car Nothing pour la chaîne sera évalué à null

A partir de la spécification du langage Visual Basic sur les opérateurs relationnels pour le type String:

Les opérateurs renvoient le résultat de la comparaison des deux valeurs à l'aide de soit une comparaison binaire ou une comparaison de texte. La comparaison utilisée est déterminé par l'environnement de compilation et l'option Compare déclaration. Une comparaison binaire détermine si le Unicode numérique la valeur de chaque caractère dans chaque chaîne est la même. Une comparaison de texte effectue une comparaison de texte Unicode basée sur la culture actuelle utilisée sur le .NET Framework. Lors d'une comparaison de chaînes, une référence null est équivalent au littéral de chaîne "".

Pour vérifier l’égalité des chaînes dans vb.net, vous devez utiliser la méthode String.Equals ou l’opérateur Is

Basé sur les spécifications de langue ci-dessus

Ma compréhension était que les deux null et Nothing sont les mêmes. Mais ci-dessus Le code explique clairement que ce n'est pas le cas.

Ils ne sont pas identiques, Nothing dans vb.net est équivalent à default(T) en C #

Quel est l'équivalent de C # null dans VB.NET?

En C #, vous ne pouvez pas définir null sur les types de valeur. Par conséquent, pour les types de référence (String), l'équivalent de C # null dans vb.net sera Nothing.
Par exemple (null == default(String))

6
Fabio

La version finale de la réponse acceptée répond correctement à la question. Cependant, Fabio a ajouté des informations utiles à sa réponse, mais il contient un certain nombre d'informations et de concepts incorrects. Donc, cette réponse est une tentative de fusionner les deux réponses en une réponse plus complète avec les informations correctes.

Tout d'abord, Nothing dans VB est équivalent à null en C #, votre compréhension est donc correcte, au moins partiellement (car il ne s'agit que d'une utilisation du mot clé Nothing). Cela a été reflété dans la littérature MSDN, bien qu'il ait récemment disparu et ait été remplacé par Word null dans de nombreux commentaires. Votre confusion provient du comportement et des fonctionnalités de VB qui diffèrent de celles de C # et les programmeurs issus d'autres langues et non expérimentés dans VB se perdent dans les résultats.

Comme indiqué dans la réponse acceptée, la question est considérée comme une comparaison de chaîne par VB car l'un des opérandes est une chaîne. Dans les comparaisons de chaînes, VB traite Nothing de la même manière que la chaîne vide "", conformément à MSDN :

Les comparaisons numériques traitent rien comme 0. Les comparaisons de chaînes traitent rien comme "" (une chaîne vide).

Maintenant, pourquoi cela se passe dans VB? Cela se produit parce que VB utilise le mot clé Nothing pour deux choses différentes (de la même manière qu'il utilise l'opérateur = pour deux choses différentes, affectation et comparaison). La première utilisation est équivalente à null en C # comme je l’ai mentionné ci-dessus. La deuxième utilisation est équivalente à l'opérateur default(T) en C #. Comme avec l'opérateur =, VB sait comment utiliser Nothing en fonction du contexte. Exemples:

Dans cette ligne, VB utilise Nothing comme null:

Console.WriteLine(s Is Nothing) //C#: (s == null)

Dans ces lignes, VB utilise Nothing comme default(T) pour affecter la valeur par défaut à la variable:

Dim s As String = Nothing //C#: string s = default(string);
Dim i As Integer = Nothing //C#: int i = default(int);

Enfin, lors de la comparaison de variables de types différents, VB et C # convertissent un opérande pour correspondre au type de l'autre opérande. Par exemple, si vous comparez des valeurs doubles et entières. VB et C # renverront true pour cette ligne:

Console.WriteLine(5.0 = 5) //C#: (5.0 == 5)

Cependant, VB et C # diffèrent en ce que les types peuvent être convertis en quoi. De même, les chaînes vides "" et null sont traitées de la même manière dans les comparaisons de chaînes en VB, mais pas en C #. Cela facilite les choses dans la plupart des cas, ce qui est connu de VB en général. Donc, vous pouvez facilement tester si votre chaîne n'a pas de valeur comme celle-ci:

Console.WriteLine(s = Nothing)
Console.WriteLine(s = "")

Les deux lignes renverront le même résultat car VB traite Nothing comme "" pour comparaison. En C #, vous ne pouvez pas faire cela et vous devez tester pour les deux comme ceci:

Console.WriteLine(s == null && s == "")

De toute évidence, VB est plus facile et plus court que C # dans ce cas, qui est le plus courant. Toutefois, cela entraîne une perte de contrôle. Dans les cas moins fréquents où vous souhaitez uniquement tester la référence null, C # devient évidemment meilleur car vous pouvez toujours utiliser l'opérateur ==:

Console.WriteLine(s == null)

En VB, vous ne pouvez pas utiliser l'opérateur = et vous devez en utiliser un autre, l'opérateur Is:

Console.WriteLine(s Is Nothing)

De plus, bien que VB soit plus facile au point précédent, C # est plus clair. C'est pourquoi, du point de vue de la clarté du code, cette ligne peut être utilisée dans les deux langues avec le même résultat:

Console.WriteLine(string.IsNullOrEmpty(s))
2
Racil Hilan

Nothing dans VB varie selon le type d'objet: - Les types de référence correspondent à null - les types de valeur correspondent à la valeur par défaut; qui pour un type nullable est null

1
Mad Myche

Microsoft reference a raison, dit-on

Représente la valeur par défaut de tout type de données.

Mais ce n'était pas assez clair pour moi jusqu'à ce que je crée une application console VB.NET avec le code suivant:

    Dim myText As String = Nothing
    Dim myInt As Integer = Nothing
    Dim myFloat As Single = Nothing
    Dim myBoolean As Boolean = Nothing
    Dim myDate As DateTime = Nothing

décompilé en utilisant ILSpy et le code résultant C # était:

    string myText = null;
    int myInt = 0;
    float myFloat = 0f;
    bool myBoolean = false;
    DateTime myDate = DateTime.MinValue;

Il n'y a que Nothing littéral pour spécifier une valeur null dans VB.NET.

De C # default(Type) est équivalent à VB Nothing

0
Ivanzinho