Конструктивные цепочки и нулевые эталонные тесты - PullRequest
3 голосов
/ 03 июня 2011

Как проверить нулевое значение ДО вызова другого конструктора?

Скажи:

  ' 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

Ответы [ 4 ]

3 голосов
/ 03 июня 2011

Я делаю это в C # с помощью статического метода в конвейере, например:

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 Предположим, вы можете сделать что-то очень похожее в VB.(общие методы?)

Отражатель заверяет меня, что это означает:

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
2 голосов
/ 03 июня 2011

Простой способ справиться с этим - использовать идею "именованных конструкторов", или фабричных методов.

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 , который использует фабричные методы, чтобы избежать неоднозначности.

2 голосов
/ 03 июня 2011

Уродливый обходной путь - это метод расширения:

<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

Используется как:

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

End Sub
0 голосов
/ 03 июня 2011

Первоначально я хотел сказать, что у вас даже нет конструктора, который использует экземпляр MyHour. Вместо этого сделайте, чтобы пользователь проверил Ничто вне класса:

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

Однако использование частного конструктора для фактического конструирования объекта, например, может работать (не проверено):

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...