New to OOP - Need Validation

subaru_sti

Active member
Joined
Jul 4, 2009
Messages
34
Programming Experience
Beginner
Hello.

I'm new to OOP and .Net and just need to make sure I am doing things correctly. Am I missing anything or are there better ways of doing this? Here is the first class I have written, for GSP coordinates.

VB.NET:
Namespace GPS
    Public Class Coordinate

        Private _latitude As String
        Private _longitude As String

        Public Sub New(ByVal Latitude As Double, ByVal Longitude As Double)
            MyBase.New()

            Me.Latitude = Latitude
            Me.Longitude = Longitude
        End Sub

        Public Property Latitude() As Double
            Get
                Return _latitude
            End Get
            Set(ByVal value As Double)
                If value > 90 Then Throw New ArgumentOutOfRangeException("latitude", "Latitude cannot be greater than 90.")
                If value < -90 Then Throw New ArgumentOutOfRangeException("latitude", "Latitude cannot be less than -90.")

                _latitude = value
            End Set
        End Property

        Public Property Longitude() As Double
            Get
                Return _longitude
            End Get
            Set(ByVal value As Double)
                If value > 180 Then Throw New ArgumentOutOfRangeException("longitude", "Longitude cannot be greater than 180.")
                If value < -180 Then Throw New ArgumentOutOfRangeException("longitude", "Longitude cannot be less than -180.")

                _longitude = value
            End Set
        End Property

    End Class
End Namespace

Stephen
 
Double is a value type, it can only have valid values in it's range. To be able to use Nothing reference it must be declared as Nullable (see post 6). If you just declare a Double variable without assigning it anything it will hold the default value of 0. You really should read the 'Nullable Value Types' article I linked.
 
John,

I read the "Nullable Value Types" article, but the following does seem to work without using Nullable:

VB.NET:
Dim direction as String = "abc"
Dim newDirection As Double
Double.TryParse(direction, newDirection)
Dim myDirection As New Direction(newDirection)

Return Utility.isNothingReturnNA(myDirection.Course())

VB.NET:
    Public Class Direction
        Private _course As Double

        Public Sub New(ByVal course As Double)
            Me.Course = course
        End Sub

        Public Property Course() As Double
            Get
                Return _course
            End Get
            Set(ByVal value As Double)
                If value > 360 Then Throw New ArgumentOutOfRangeException("Course cannot be greater than 360.")
                If value < 0 Then Throw New ArgumentOutOfRangeException("Course cannot be less than 0.")

                _course = value
            End Set
        End Property
    End Class

    Public Class Utility
        Public Shared Function isNothingReturnNA(ByVal value As Double) As String
            If value = Nothing Then
                Return "N/A"
            Else
                Return value.ToString()
            End If
        End Function
    End Class

Stephen
 
That only "seems" to work because you haven't tested it thoroughly. Try this code to see why you need to use a nullable type:
VB.NET:
Dim dbl1 As Double
Dim dbl2 As Double = 0
Dim dbl3 As Double = Nothing

If dbl1 = Nothing Then
    MessageBox.Show("dbl1 = Nothing")
Else
    MessageBox.Show("dbl1 <> Nothing")
End If

If dbl1 = 0 Then
    MessageBox.Show("dbl1 = 0")
Else
    MessageBox.Show("dbl1 <> 0")
End If

If dbl2 = Nothing Then
    MessageBox.Show("dbl2 = Nothing")
Else
    MessageBox.Show("dbl2 <> Nothing")
End If

If dbl2 = 0 Then
    MessageBox.Show("dbl2 = 0")
Else
    MessageBox.Show("dbl2 <> 0")
End If

If dbl3 = Nothing Then
    MessageBox.Show("dbl3 = Nothing")
Else
    MessageBox.Show("dbl3 <> Nothing")
End If

If dbl3 = 0 Then
    MessageBox.Show("dbl3 = 0")
Else
    MessageBox.Show("dbl3 <> 0")
End If
As you can see, all three variables report that they are equal to both Nothing and 0, so there's no way to distinguish between Nothing and 0 without using a nullable type.
 
Okay, I see.

So where do I set the nullable type in the code in my previous post?

Stephen
Read the information that has already been provided.
 
I have and I read the article too. After I change the variables to Nullable (Of Double) I get "disallows implicit conversion" errors all over the place.

Stephen
 
Your variables are now a different type. You can't assign a Double? value to a Double variable because they are not the same type. I explained how to test whether a nullable object has a value and how to get that value in post #6. What you would originally have got from the variable itself you now get from the Value property, assuming the HasValue property is True.
 
Okay. I think I figured this out. The reason I was having issues is because in the TryParse, you can't use the Nullable type like I was doing before when it was a double. Is there anyway to just use one variable or do you have to use two?

VB.NET:
    Public Function DoStuff(ByVal TheString As String) As String
        Dim TheDouble As Nullable(Of Double) = Nothing
        Dim tempValue As Double

        If Double.TryParse(TheString, tempValue) Then
            TheDouble = tempValue
        End If

        If TheDouble.HasValue Then
            Return "Valid double: " & TheDouble.Value.ToString
        Else
            Return "Invalid double"
        End If
    End Function

Does the above code look okay?

Stephen
 
I think I am starting to understand this better... Instead of using that Nullable type, which I was having troubles incorporating into my class, I added an IsValid property to the class. I also found out you can pass different types through the constructor and handle them in different ways. This should accomplish the same thing as Nullable, right? As long as you check IsValid when you do stuff with the value.

VB.NET:
    Public Class Heading
        Private _direction As Double
        Private _isValid As Boolean

        Public Sub New(ByVal direction As Double)
            Me.Direction = direction
        End Sub

        Public Sub New(ByVal direction As String)
            Dim tempDirection As Double
            If Double.TryParse(direction, tempDirection) Then
                Me.Direction = tempDirection
            Else
                _direction = 0
                _isValid = False
            End If
        End Sub

        Public Property Direction() As Double
            Get
                Return _direction
            End Get
            Set(ByVal value As Double)
                If value > 360 Or value < 0 Then
                    '-- Invalid direction
                    _direction = 0
                    _isValid = False
                Else
                    '-- Valid direction
                    _direction = value
                    _isValid = True
                End If
            End Set
        End Property

        Public ReadOnly Property IsValid() As Boolean
            Get
                Return _isValid
            End Get
        End Property
    End Class

Stephen
 
I like the way you described it with Nullable but couldn't figure out how to use it with the class, until now. How does this look:

VB.NET:
    Public Class GPStest
        Private _speed As Nullable(Of Double)

        Public Sub New(ByVal speed As Double)
            Me.Speed = speed
        End Sub

        Public Sub New(ByVal speed As String)
            Dim tempSpeed As Double
            If Double.TryParse(speed, tempSpeed) Then
                Me.Speed = tempSpeed
            Else
                _speed = Nothing
            End If
        End Sub

        Public Property Speed() As Nullable(Of Double)
            Get
                Return _speed
            End Get
            Set(ByVal value As Nullable(Of Double))
                If value.Value < 0 Then
                    '-- Invalid speed
                    _speed = Nothing
                Else
                    '-- Valid speed
                    _speed = value
                End If
            End Set
        End Property
    End Class

And to use it:

VB.NET:
Dim var As New GPStest(Math.PI)

If var.Speed.HasValue Then
    Return "Has Value: " & var.Speed.ToString
Else
    Return "Has No Value"
End If

Stephen
 
I see three issues there:

1. Your Speed property is Double? yet there's no way to create an instance without specifying a speed. I would suggest that either your constructor parameter should be Double? too or else you should have another constructor with no parameters.

2. That constructor with a String parameter really has no place in that class. If client code has a string then it should the the client code's responsibility to convert it, not that class's.

3. In your Speed setter you access value.Value without testing value.HasValue, which will lead to an exception if the property is set to Nothing.
 
1. Speed gets passed in as m/s from a web service so it needs to be a double. You could have 25.39 m/s...
2. The client could also pass N/A so that string parameter is there to check for that and change all string values to NOTHING and set Nullable.HasValue to false. Should I be doing this outside of the class?
3. I changed it to the following

VB.NET:
            Set(ByVal value As Nullable(Of Double))
                If _speed.HasValue Then
                    If value.Value < 0 Then
                        '-- Invalid speed
                        _speed = Nothing
                    Else
                        '-- Valid speed
                        _speed = value
                    End If
                Else
                    _speed = Nothing
                End If
            End Set

Stephen
 
Back
Top