2011-05-03 17 views
63

En VB.NET, ¿hay alguna manera de establecer una variable DateTime en "no establecida"? ¿Y por qué es posible establecer un DateTime en Nothing, pero no posible para verificar si es Nothing? Por ejemplo:¿Por qué no puedo verificar si un 'DateTime' es 'Nothing'?

Dim d As DateTime = Nothing 
Dim boolNotSet As Boolean = d Is Nothing 

La segunda declaración tiros este error:

'Is' operator does not accept operands of type 'Date'. Operands must be reference or 
nullable types. 
+1

Además de la respuesta de John Gant a continuación, también puede verificar si la variable datetime = Nothing (Observe el = en lugar de "is"). – NYSystemsAnalyst

+0

Gracias, usando Dim boolNotSet As Boolean = d = Nada parece ser la solución más simple en este momento. Interesante con el casting Nullable nunca visto antes de – Muleskinner

+0

@Chris - Creo que está usando VB –

Respuesta

117

Esta es una de las mayores fuentes de confusión con VB.Net, IMO.

Nothing en VB.Net es el equivalente a default(T) en C#: el valor predeterminado para el tipo especificado.

  • Para los tipos de valor, esto es, esencialmente, el equivalente a 'cero': 0 para Integer, False para Boolean, DateTime.MinValue para DateTime, ...
  • Para los tipos de referencia, que es el valor null (una referencia eso se refiere a, bueno, nada).

La declaración d Is Nothing es por lo tanto equivalente a d Is DateTime.MinValue, que obviamente no se compila.

Soluciones: como otros han dicho

  • Cualquiera de usar DateTime? (es decir Nullable(Of DateTime)). Esta es mi solución preferida.
  • O utilice d = DateTime.MinValue o equivalentemente d = Nothing

En el contexto del código original, se puede utilizar:

Dim d As DateTime? = Nothing 
Dim boolNotSet As Boolean = d.HasValue 
10

DateTime es un tipo de valor, por lo que no puede ser nulo. Puede verificar que sea igual a DateTime.MinValue, o puede usar Nullable(Of DateTime) en su lugar.

VB a veces "amablemente" te hace pensar que está haciendo algo que no es. Cuando te permite establecer una fecha en Nothing, en realidad está estableciéndolo en algún otro valor, tal vez MinValue.

Consulte this question para obtener una amplia explicación de los tipos de valores en comparación con los tipos de referencia.

2

DateTime es valor tipo, lo que significa que siempre tiene algún valor.

Es como un número entero: puede ser 0, o 1, o menor que cero, pero nunca puede ser "nada".

Si desea un DateTime que pueda tomar el valor Nothing, use un DateTime que se puede anular.

1

En cualquier lenguaje de programación, tener cuidado al usar valores nulos. El ejemplo anterior muestra otro problema. Si usa un tipo de Nullable, eso significa que las variables instanciadas de ese tipo pueden contener el valor System.DBNull.Valor; no es que haya cambiado la interpretación de establecer el valor a predeterminado usando "= Nothing" o que el Object del valor ahora puede soportar una referencia nula. Solo una advertencia ... ¡feliz codificación!

Puede crear una clase separada que contenga un tipo de valor. Un objeto creado a partir de dicha clase sería un tipo de referencia, al que se le podría asignar Nada. Un ejemplo:

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 

End Class

'en 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 

entonces usted podría escoger y elegir overridables para que haga lo que necesita. Mucho trabajo, pero si realmente lo necesita, puede hacerlo.

3

Algunos ejemplos sobre cómo trabajar con valores nulos DateTime.

(Ver Nullable Value Types (Visual Basic) por más.)

' 
' 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] 

también, sobre cómo comprobar si una variable es nula (de Nothing (Visual Basic)):

When checking whether a reference (or nullable value type) variable is null, do not use = Nothing or <> Nothing . Always use Is Nothing or IsNot Nothing .
0

Una forma de evitar esto sería use el tipo de datos Object en su lugar:

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 

entonces se puede establecer la fecha para nada, así:

MyDate = Nothing 
Dim theDate As Date = MyDate 
If theDate = Nothing Then 
    'date is nothing 
End If 
1

También puede utilizar a continuación sólo simple para comprobar:

If startDate <> Nothing Then 
your logic 
End If 

Se comprobará que la variable startDate de DateTime tipo de datos es nulo o no .

Cuestiones relacionadas