System.Convert.DBNull - affecter une valeur null à une variable [Résolu]

Signaler
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
-
romagny13
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
-
Bonjour,
La question semble simple et pourtant cela peut etre un casse tete ...

je cherches à affecter une valeur null à une variable
ex:
j'ai une variable de type DateTime ,
si on ne lui affecte aucune valeur  elle a par défaut la valeur 01/01/0001 00:00:00
aussi je voudrais tout simplement que cette variable soit vide donc null

c'est pareil pour un int par exemple si on ne lui affecte pas de valeur par défaut il aura 0 , mais je ne veux tout simplement que cette variable soit "vide"

j'ai essayé avec UneVariableDeTypeDate = System.

Convert.DBNull;

mais j'ai des problêmes de cast même en essayant
UneVariableDeTypeDate = (

DateTime
) System.
Convert.DBNull;

j'ai regardé au niveau des datasets et j'ai observé que selon que une datarow a une valeur ou non le type de la datarow est changé dynamiquement selon exactement ce même type de ligne de code que si dessus
en fait la classe DataRow du dataset a des methodes SetNull pour chaque champ

mais pas moyen c'est quand même important car on a parfois besoin justement que nos variables restent vides

certains vont peut etre me parler des nullables (ce peut etre une solution) mais je pense aussi à .NET 1.0 et il n'y a pas de nullables en .NET 1.0 (a moins de se recréer la structure mais bon lol) enfin bref

si vous savez comment affecter une valeur null à une varible de type int ou datetime (par exemple) merci de me le dire :p

22 réponses

Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Salut,
On ne peut pas assigner des valeurs null aux values types. Une solution est effectivement de passer par les types Nullable:

Nullable<
DateTime> dt1 =
null;
(
DateTime? dt2 =
null;)

<hr />
-Blog-
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Le SetNull du DataEow applique un System.DBNull.Value sur l'index spécifié. Comme c'est une collection d'object, pas de problème...
Je ne vois pas le rapport avec un value type ?

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Le DataSet manipule de l'object, qui lui est un type reference et peut donc etre une référence nulle.
Mais cette solution de typer object, en dehors d'être relativement moche, entraîne fatalement du boxing/unboxing...
Donc si tu veux vraiment gérer à la mano, l'utilisation d'un booléean d'état me parait plus propre.

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Par défaut, un DateTime à DateTime.MinValue comme valeur, un int est initialisé à 0.
Un type qui est nullable int? x = 0, reste un value type !

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Salut,

La réponse courte : tu ne peux pas ^^

"mais pas moyen c'est quand même important car on a parfois besoin justement que nos variables restent vides"
Oui, les types nullables n'ont pas été pensés par hasard...

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Décidément... :p

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
10 minutes de retard. Encore en week-end?

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Exactement :-D

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
2
"La réponse courte : tu ne peux pas ^^"

je clique sur réponse refusée il est ou le bouton ? :p

ba je vais continuer quand même à chercher, oui les nullables peuvent etre un debut de solution mais en NET 1.0 ..
merci pour votre aide
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
2
quoique si il doit y avoir une solution le dataset le fait impeccablement, je vais essayer de voir comment ..
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
coq> Avoues, tu le fais exprès ?

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Je l'aurais un jour, je l'aurais !...

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
2
Oui
en fait c'est evident un object peut etre null
mais pas un int ni un datetime ne pourra jamais l'etre et serait initilaiser automatiquement à 01/01/0001 etc . et  0 ?
bon ba super donc en .NET 2.0 y a les nullables
et en .NET 1.0 ba de la bidouille lol
++
Messages postés
687
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
27 août 2014
2
tiens j'ai trouvé une possibilté qui marche aussi bien en .NET 1.0 que .NET 2.0

public

object SetTo(
object o,System.
Type oType){

if (oType.Name ==
typeof(System.
Int32).Name){

o =

new
Int32();}

if (oType.Name ==
typeof(System.
DateTime).Name){

o =

new
DateTime();}

if (oType.Name ==
typeof(System.
DBNull).Name){

o = System.

Convert.DBNull;}

return o;}

// ou encore

public

object SetDBNull(
object o){

o = System.

Convert.DBNull;

return o;}

Utilsation :

object MonObjet;MonObjet =

new
DateTime();MonObjet = SetDBNull(MonObjet,

typeof(System.
DBNull));

// ou

//MonObjet = SetTo(MonObjet,typeof(System.DBNull));

// ou encoreMonObjet = SetDBNull(MonObjet,

typeof(System.
DateTime));MonObjet = SetTo(MonObjet,

typeof(System.
DBNull));

le code des méthodes serait à améliorer mais elles pourraient devenir utiles

cela permet de passer instantanément le type d'un object
ainsi une variable peut etre de type DateTime et avoir tous les avantages
et ensuite lui a&ffecter DNull

en .NET 2.0 il y a même certainement moyen de l'améliorer encore avec les generics

mais qu'est ce que vous dites ?
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Mais qu'est ce que c'est cette horreur ???
A aucun moment tu n'affectes une valeur null à un DateTime ou un int dans ton code. Ce que tu fais, c'est boxer ton type dans un object (qui est un reference type et qui peut donc être null).
Bref, code très moche et bien sûr très lent.

A éviter autant que possible !

<hr />
-Blog-
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Et à ce moment, c'est pas vraiment utile de faire toutes ces méthodes qui check le type, suffit de faire

object monObject =
new
DateTime(); // N'importe quel value-type qui va être boxé en object
monObject =
null;

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Je persiste à préférer un modèle mettant en oeuvre un booléen déterminant l'état "indéfini". :-)

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
44
Voui, le désavantage dans ce cas c'est qu'il faut faire un wrapper juste pour rajouter l'état du value-type... Au moins, on n'évite le boxing.
C'est déjà pas mal

<hr />
-Blog-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
76
Oui, ça fait un type de plus à maintenir, mais c'est le prix à payer pour garder aussi un typage fort.
(Vive .NET 2.0)

/*
coq
MVP Visual C#
CoqBlog
*/
1 2