Pourquoi ne puis-je pas vérifier si un "DateTime" est "rien"?
In VB.NET, y a-t-il un moyen de définir une variable DateTime
à "non défini"? Et pourquoi est-il possible de définir un DateTime
à Nothing
, mais pas possible de vérifier si c'est Nothing
? Par exemple:
Dim d As DateTime = Nothing
Dim boolNotSet As Boolean = d Is Nothing
la deuxième déclaration jette cette erreur:
'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.
8 réponses
C'est l'une des plus grandes sources de confusion avec VB.Net, IMO.
Nothing
VB.Net est l'équivalent de default(T)
en C#: la valeur par défaut pour le type donné.
- Pour les types de valeur, c'est essentiellement l'équivalent de "zéro":
0
pourInteger
,False
pourBoolean
,DateTime.MinValue
pourDateTime
, ... - pour les types de référence, c'est le
null
valeur (une référence qui se rapporte à rien).
la mention d Is Nothing
est donc équivalente à d Is DateTime.MinValue
, qui évidemment ne compile pas.
Solutions: Comme d'autres l'ont dit
- utilisez
DateTime?
(i.e.Nullable(Of DateTime)
). C'est ma solution préférée. - ou utiliser
d = DateTime.MinValue
ou l'équivalentd = Nothing
dans le contexte du code original, vous pouvez utiliser:
Dim d As DateTime? = Nothing
Dim boolNotSet As Boolean = d.HasValue
DateTime est un type de valeur, c'est pourquoi il ne peut pas être null. Vous pouvez vérifier qu'il est égal à DateTime.MinValue
, ou vous pouvez utiliser Nullable(Of DateTime)
à la place.
VB parfois "helpfully" vous fait penser qu'il fait quelque chose qu'il n'est pas. Quand il vous permet de fixer une Date à zéro, il est vraiment la mise à une autre valeur, peut-être MinValue.
Voir cette question pour une discussion approfondie des types de valeur contre les types de référence.
Quelques exemples sur la façon de travailler avec nullable DateTime
valeurs".
(Voir Nullable Types de Valeur (Visual Basic) pour plus d'.)
'
' An ordinary DateTime declaration. It is *not* nullable. Setting it to
' 'Nothing' actually results in a non-null value.
'
Dim d1 As DateTime = Nothing
Console.WriteLine(String.Format("d1 = [{0}]\n", d1))
' Output: d1 = [1/1/0001 12:00:00 AM]
' Console.WriteLine(String.Format("d1 is Nothing? [{0}]\n", (d1 Is Nothing)))
'
' Compilation error on above expression '(d1 Is Nothing)':
'
' 'Is' operator does not accept operands of type 'Date'.
' Operands must be reference or nullable types.
'
' Three different but equivalent ways to declare a DateTime
' nullable:
'
Dim d2? As DateTime = Nothing
Console.WriteLine(String.Format("d2 = [{0}][{1}]\n", d2, (d2 Is Nothing)))
' Output: d2 = [][True]
Dim d3 As DateTime? = Nothing
Console.WriteLine(String.Format("d3 = [{0}][{1}]\n", d3, (d3 Is Nothing)))
' Output: d3 = [][True]
Dim d4 As Nullable(Of DateTime) = Nothing
Console.WriteLine(String.Format("d4 = [{0}][{1}]\n", d4, (d4 Is Nothing)))
' Output: d4 = [][True]
aussi, sur la façon de vérifier si une variable est null (de rien (Visual Basic) ):
Pour vérifier si une variable de référence (ou de type de valeur NULL) est null , do n'utilisez pas= Nothing
ou<> Nothing
. Toujours utiliserIs Nothing
ouIsNot Nothing
.
DateTime est un type de valeur , ce qui signifie qu'il a toujours une certaine valeur.
c'est comme un entier - il peut être 0, ou 1, ou moins que zéro, mais il ne peut jamais être"rien".
si vous voulez un DateTime qui peut prendre la valeur rien, utilisez un DateTime nul.
dans tout langage de programmation, soyez prudent lorsque vous utilisez Nulls. L'exemple ci-dessus montre un autre problème. Si vous utilisez un type de Nullable, cela signifie que les variables instanciées à partir de ce type peuvent contenir le système de valeurs.DBNull.Valeur; non pas qu'il ait changé l'interprétation de la valeur par défaut en utilisant "= rien" ou que l'objet de la valeur puisse maintenant supporter une référence nulle. Juste un avertissement... amusez-vous bien!
vous pouvez créer une classe séparée contenant un type de valeur. Un objet créé à partir d'une telle classe serait un type de référence, qui ne pourrait être affecté à rien. Un exemple:
Public Class DateTimeNullable
Private _value As DateTime
'properties
Public Property Value() As DateTime
Get
Return _value
End Get
Set(ByVal value As DateTime)
_value = value
End Set
End Property
'constructors
Public Sub New()
Value = DateTime.MinValue
End Sub
Public Sub New(ByVal dt As DateTime)
Value = dt
End Sub
'overridables
Public Overrides Function ToString() As String
Return Value.ToString()
End Function
Fin De La Classe
'dans le Main():
Dim dtn As DateTimeNullable = Nothing
Dim strTest1 As String = "Falied"
Dim strTest2 As String = "Failed"
If dtn Is Nothing Then strTest1 = "Succeeded"
dtn = New DateTimeNullable(DateTime.Now)
If dtn Is Nothing Then strTest2 = "Succeeded"
Console.WriteLine("test1: " & strTest1)
Console.WriteLine("test2: " & strTest2)
Console.WriteLine(".ToString() = " & dtn.ToString())
Console.WriteLine(".Value.ToString() = " & dtn.Value.ToString())
Console.ReadKey()
' Output:
'test1: Succeeded()
'test2: Failed()
'.ToString() = 4/10/2012 11:28:10 AM
'.Value.ToString() = 4/10/2012 11:28:10 AM
alors vous pouvez choisir et choisir des produits overridables pour le faire faire ce que vous avez besoin. Beaucoup de travail, mais si vous en avez vraiment besoin, vous pouvez le faire.
vous pouvez également utiliser ci-dessous juste pour vérifier:
If startDate <> Nothing Then
your logic
End If
il vérifiera que la variable startDate de DateTime datatype est nulle ou non.
une façon d'éviter cela serait d'utiliser le type de données objet à la place:
Private _myDate As Object
Private Property MyDate As Date
Get
If IsNothing(_myDate) Then Return Nothing
Return CDate(_myDate)
End Get
Set(value As Date)
If date = Nothing Then
_myDate = Nothing
Return
End If
_myDate = value
End Set
End Property
alors vous pouvez définir la date à rien comme cela:
MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
'date is nothing
End If
Vous pouvez le vérifier comme ci-dessous :
if varDate = "#01/01/0001#" then
' blank date. do something.
else
' Date is not blank. Do some other thing
end if