Je ne suis pas daccord avec la tendance ici. Je vais aller sur le dossier:
Je ne crois pas qu' DBNull
sert aucune fin utile; il s'y ajoute une confusion inutile, tout en contribuant pratiquement aucune valeur.
L'argument est souvent mis en avant que la null
est une référence non valide, et qu' DBNull
est un objet null; elle n'est pas vraie. Par exemple:
int? x = null;
ce n'est pas une référence non valide"; c'est un null
de la valeur. En effet, null
signifie que tout ce que vous voulez dire, et franchement, je n'ai absolument aucun problème à travailler avec des valeurs qui peuvent être null
(en effet, même dans SQL nous avons besoin pour travailler correctement avec null
- rien ne change ici). De même, la "objet nul motif" n'a de sens que si vous êtes réellement en la traitant comme un objet en programmation orientée objet, mais si nous avons une valeur qui peut être "notre valeur, ou un DBNull
" ensuite, il doit être object
, donc on ne peut pas être quelque chose d'utile.
Il y a beaucoup de mauvaises choses avec DBNull
:
- il vous oblige à travailler avec des
object
, depuis seulement object
peut contenir DBNull
ou une autre valeur
- il n'y a pas de réelle différence entre "pourrait être une valeur ou
DBNull
" vs "pourrait être une valeur ou null
"
- l'argument qu'elle découle d'1.1 (pré-nullable-types) est vide de sens; nous pourrions utiliser
null
parfaitement bien dans 1.1
- la plupart des Api ont "est-il nul?" méthodes, par exemple
DBDataReader.IsDBNull
ou DataRow.IsNull
- qui ne requièrent DBNull
existe sur le plan de l'API
-
DBNull
d'échec en termes de null-coalescence; value ?? defaultValue
ne fonctionne pas si la valeur est DBNull
-
DBNull.Value
ne peut pas être utilisé dans les paramètres facultatifs, car ce n'est pas une constante
- l'exécution de la sémantique de l'
DBNull
identiques à la sémantique de l' null
; en particulier, DBNull
réellement égaux DBNull
- de sorte qu'il ne permet pas de faire le travail de représentation de la sémantique SQL
- souvent les forces de la valeur des valeurs du type à être mis en boîte car il utilise
object
- si vous avez besoin de tester pour
DBNull
, vous pourriez aussi bien avoir testé pour seulement null
- il provoque d'énormes problèmes pour des choses comme la commande des paramètres, avec un comportement idiot que si un paramètre a un
null
de la valeur il n'est pas envoyé... eh bien, en voilà une idée: si vous ne voulez pas un paramètre envoyé - ne pas ajouter à la collection de paramètres
- tous les ORM je pense, fonctionne parfaitement bien sans aucun besoin ou de l'utilisation de
DBNull
, sauf comme un supplément de nuisance lorsque l'on parle à l'ADO.NET code
Le seul , même à distance argument convaincant que j'ai jamais vu pour justifier l' existence d'une telle valeur en DataTable
, lors du passage en valeurs afin de créer une nouvelle ligne; un null
signifie "utiliser par défaut", une DBNull
est explicitement null franchement cette API pourrait avoir eu un traitement spécifique pour ce cas - imaginaire DataRow.DefaultValue
par exemple serait beaucoup mieux que de l'introduction d'un DBNull.Value
qui infecte de vastes portions de code pour aucune raison.
De même, l' ExecuteScalar
scénario est... au mieux précaire; si vous exécutez un scalaire méthode, vous attendre à un résultat. Dans le scénario où il n'y a pas de lignes, de revenir null
ne semble pas trop terrible. Si vous avez absolument besoin de lever l'ambiguïté entre "pas de lignes" et "une seule valeur null est retournée", il y a le lecteur de l'API.
Ce navire a navigué il y a longtemps, et il est beaucoup trop tard pour le corriger. Mais! S'il vous plaît ne pas penser que tout le monde est d'accord que c'est une "évidence" de la chose. Beaucoup de développeurs ne pas voir la valeur dans ce drôle de pli sur la BCL.
En fait je me demande si tout cela provient de deux choses:
- avoir à utiliser le mot -
Nothing
au lieu de quelque chose avec la valeur "null" dans VB
- être en mesure de nous l'
if(value is DBNull)
de la syntaxe qui "ressemble à SQL", plutôt que de oh-so-tricky if(value==null)
Résumé:
Avoir 3 options (null
, DBNull
, ou une valeur réelle) n'est utile que s'il existe un véritable exemple où vous avez besoin de lever l'ambiguïté entre les 3 cas différents. Je n'ai pas encore vu une occasion où j'ai besoin de représenter les deux "null" états, de sorte qu' DBNull
est entièrement redondant étant donné qu' null
existe déjà et a beaucoup mieux la langue et à l'exécution.