「DateTime」が「Nothing」であるかどうかを確認できないのはなぜですか?


81

VB.NETで、DateTime変数を「未設定」に設定する方法はありますか?また、にを設定できるDateTimeのにNothing、そうであるかどうかを確認できないのNothingなぜですか?例えば:

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

2番目のステートメントはこのエラーをスローします:

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

1
以下のJohnGantの回答に加えて、日時変数= Nothing( "is"ではなく=に注意)かどうかを確認することもできます。
DCNYAM 2011年

おかげで、Dim boolNotSet As Boolean = d =を使用する現在最も単純な解決策のように思われるものはありません。これまでに見たことのないNullableキャスティングで興味深い
Muleskinner 2011年

@ Chris-彼はVBを​​使用していると思います
Karthik Ratnam

@Karthik Ratnam、そうですが、それは同じことであり、@ MarcGravellの答えはすべてのポイントを理解します。
クリス・ハース

1
@NYSystemsAnalyst:Nothing(Visual Basic)によると、使用= Nothingまたは不適切<> Nothingな方法:「参照(またはnull許容値型)変数がnullかどうかを確認するときは、= Nothingまたはを使用しないでください<> Nothing。常にIs Nothingまたはを使用してくださいIsNot Nothing。」
DavidRR 2012

回答:


140

これは、VB.Net、IMOとの最大の混乱の原因の1つです。

NothingVB.Netの場合は、default(T)C#の場合と同等です。特定のタイプのデフォルト値です。

  • 値型の場合、これは基本的に「ゼロ」と同等です:0for IntegerFalsefor BooleanDateTime.MinValuefor DateTime、..。
  • 参照型の場合、それはnull値です(まあ、何も参照しない参照)。

d Is Nothingしたがって、このステートメントは、d Is DateTime.MinValue明らかにコンパイルされない、と同等です。

解決策:他の人が言っているように

  • どちらかを使用しますDateTime?(つまりNullable(Of DateTime))。これが私の好ましい解決策です。
  • または使用d = DateTime.MinValueまたは同等にd = Nothing

元のコードのコンテキストでは、次を使用できます。

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

より包括的な説明は、Anthony D.Greenのブログにあります。


1
説明してくれてありがとう。isNothing(d)は機能しませんが、d =何も機能しないことに注意してください。
PHN

12

DateTimeは値型であるため、nullにすることはできません。と等しいDateTime.MinValueかどうかを確認するか、Nullable(Of DateTime)代わりに使用できます。

VBは、「役立つ」ことで、そうではないことをしていると思わせることがあります。日付をNothingに設定できる場合、実際には他の値、おそらくMinValueに設定されています。

値型と参照型の詳細については、この質問を参照してください。


4

DateTimeは値型です。つまり、常に何らかの値があります。

これは整数のようなものです。0、1、または0未満にすることができますが、「何もない」ことはできません。

値NothingをとることができるDateTimeが必要な場合は、NullableDateTimeを使用してください。


4

null許容DateTime値の操作に関するいくつかの例。

(詳細については、NULL可能値タイプ(Visual Basic)を参照してください。)

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

また、変数がnullかどうかを確認する方法について(Nothing(Visual Basic)から):

参照(またはnull許容値型)変数がnullかどうかを確認するときは、= Nothingまたはを使用しないでください<> Nothing。常にIs Nothingまたはを使用してくださいIsNot Nothing

1

どのプログラミング言語でも、Nullを使用するときは注意してください。上記の例は別の問題を示しています。Nullableの型を使用する場合、それは、その型からインスタンス化された変数が値System.DBNull.Valueを保持できることを意味します。「= Nothing」を使用して値をデフォルトに設定する解釈が変更されたことや、値のオブジェクトがnull参照をサポートできるようになったわけではありません。ただの警告...ハッピーコーディング!

値型を含む別のクラスを作成できます。このようなクラスから作成されたオブジェクトは参照型であり、Nothingを割り当てることができます。例:

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

エンドクラス

'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

次に、オーバーライド可能なものを選択して、必要な処理を実行できます。たくさんの仕事-しかし、本当にそれが必要な場合は、それを行うことができます。


1

以下を使用して、簡単に確認することもできます。

If startDate <> Nothing Then
your logic
End If

DateTimeデータ型のstartDate変数がnullかどうかをチェックします。


1

あなたは以下のようにこれをチェックすることができます:

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

0

これを回避する方法は、代わりにObjectデータ型を使用することです。

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

次に、日付を次のように設定できます。

MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
    'date is nothing
End If
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.