Chain Designer and Zero Benchmarks

How to check a null value before calling another constructor?

Say:

  ' class MyHoyr '
  Public Sub New(ByVal myHour As MyHour)
    ' Can't doing it here !!!! '
    If myHour Is Nothing Then Throw New ArgumentNullException("myHour")

    ' Constructor call should be first '
    Me.New(myHour._timeSpan)

    ' Here is too late... '
  End Sub


  Private Sub New(ByVal timeSpan As TimeSpan)
    '.... '
  End Sub
+3
source share
4 answers

The way I do this in C # is to use a static method in a channel, for example:

public MyHour(MyHour myHour) : this(GetTimeSpan(myHour))
{}

private static TimeSpan GetTimeSpan(MyHour myHour)
{
    if(myHour== null) throw new ArgumentNullException("myHour");
    return myHour._timeSpan;
}

private MyHour(TimeSpan timeSpan)
{...}

I assume you can do something very similar in VB. (general methods?)

The reflector assures me that this means:

Public Sub New(ByVal myHour As MyHour)
    Me.New(MyHour.GetTimeSpan(myHour))
End Sub

Private Sub New(ByVal timeSpan As TimeSpan)
End Sub

Private Shared Function GetTimeSpan(ByVal myHour As MyHour) As TimeSpan
    If (myHourIs Nothing) Then
        Throw New ArgumentNullException("myHour")
    End If
    Return myHour._timeSpan
End Function
+3

An ugly workaround would be an extension method:

<Extension(), DebuggerNonUserCode()> _
Public Function EnsureNotNull(Of T As Class)(ByVal Value As T, _
                                             ByVal Arg As String) As T
    If Value Is Nothing Then Throw New ArgumentNullException(Arg)
    Return Value
End Function

Used as:

' class MyHour '
Public Sub New(ByVal myHour As MyHour)
    Me.New(myHour.EnsureNotNull("myHour")._timeSpan)

End Sub
+2

" ", factory.

Public Shared Function Create (ByValue myHour As MyHour) As Foo
  If myHour Is Nothing Then Throw New ArgumentNullException("myHour")
  Return New Foo(myHour._timeSpan)
End Function

Private Sub New(ByVal timeSpan As TimeSpan)
  '.... '
End Sub

System.Drawing.Color.FromArgb, factory, .

+2

My initial impulse was to suggest that you don't even have a constructor that accepts an instance of MyHour. Instead, ask the user to check for Nothing outside the class:

Public Function GetSomeClassInstance(ByVal mh As MyHour) As SomeClass

    If mh IsNot Nothing Then
        Return New SomeClass(mh.TimeSpan)
    Else
        Throw New ArgumentNullException("mh", "MyHour instance must not be Nothing)
    End If

End Function

However, using a private constructor to actually build an object, for example, may work (not verified):

Public Class SomeClass
    Public Sub New(ByVal mh As MyHour)
        MyClass.New(Nothing, mh)
    End Sub

    Public Sub New(ByVal ts As TimeSpan)
        MyClass.New(ts, Nothing)
    End Sub

    Private Sub New(ByVal ts As TimeSpan?, ByVal mh As MyHour)
        Dim _timeSpanToUse As TimeSpan

        If ts IsNot Nothing Then
            _timeSpanToUse = ts.Value
        Else
            If mh IsNot Nothing Then
                _timeSpanToUse = mh.TimeSpan
            Else
                Throw New ArgumentNullException("mh", "The MyHour parameter was NULL")
            End If
        End If

        'Continue using _timeSpanToUse here...
    End Sub
End Class
0
source

All Articles