Pregunta

En vb.net, ¿hay alguna forma de establecer un DateTime variable a "no establecer"? ¿Y por qué es posible establecer un DateTime a Nothing, pero no posible verificar si es Nothing? Por ejemplo:

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

La segunda declaración arroja este error:

'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.
¿Fue útil?

Solución

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

Nothing en vb.net es el equivalente de default(T) En C#: el valor predeterminado para el tipo dado.

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

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

Soluciones: como otros han dicho

  • Ya sea DateTime? (es decir Nullable(Of DateTime)). Esta es mi solución preferida.
  • O usar d = DateTime.MinValue o equivalente d = Nothing

En el contexto del código original, puede usar:

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

Una explicación más completa se puede encontrar en Blog de Anthony D. Green

Otros consejos

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

VB a veces "útilmente" te hace pensar que está haciendo algo que no es. Cuando le permite establecer una fecha en nada, realmente lo está estableciendo en algún otro valor, tal vez minvalue.

Ver esta pregunta Para una amplia discusión de tipos de valor versus tipos de referencia.

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

Es como un entero: puede ser 0, o 1 o menos de cero, pero nunca puede ser "nada".

Si desea una fecha de detección que no pueda tomar el valor nada, use una fecha de fecha anulable.

Algunos ejemplos sobre trabajar con anulable DateTime valores.

(Ver Tipos de valor anulables (Visual Basic) para 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]

Además, sobre cómo verificar si una variable es nulo (de Nada (Visual Basic)):

Al verificar si una variable de referencia (o tipo de valor anulable) es nulo, no utilice = Nothing o <> Nothing. Siempre usa Is Nothing o IsNot Nothing.

En cualquier lenguaje de programación, tenga cuidado cuando use nulos. El ejemplo anterior muestra otro problema. Si usa un tipo de anulable, eso significa que las variables instanciadas desde ese tipo pueden contener el valor System.dbnull.value; No es que haya cambiado la interpretación de establecer el valor en el valor predeterminado usando "= nada" o que el objeto del valor ahora puede admitir 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, que no 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

Clase final

'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

Luego puede elegir y elegir Inveridables para que haga lo que necesita. Mucho trabajo, pero si realmente lo necesitas, puedes hacerlo.

También puede usar a continuación simplemente para verificar:

If startDate <> Nothing Then
your logic
End If

Verificará que la variable STARTDATE del tipo de datos de DateTime sea nula o no.

Puede verificar esto como a continuación:

if varDate = "#01/01/0001#" then
       '  blank date. do something.
else
       ' Date is not blank. Do some other thing
end if

Una forma de evitar esto sería usar el tipo de datos de objetos: 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 puedes establecer la fecha en nada como:

MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
    'date is nothing
End If
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top