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
 
According to Choosing Between Classes and Structures this should be a Structure.

According to Names of Parameters the parameters should be
VB.NET:
Public Sub New(ByVal [COLOR="Green"]latitude [/COLOR]As Double, ByVal [COLOR="Green"]longitude [/COLOR]As Double)
Why have you declared the private fields as type String? The type is Double, no? 'Option Strict' to 'On' will help you write better, explicit type code.
VB.NET:
Private _latitude As [COLOR="Red"]String[/COLOR]
Private _longitude As [COLOR="Red"]String[/COLOR]
The ArgumentOutOfRangeException in property setter I'd say is correct usage.
VB.NET:
MyBase.New()
Why have you included this? You're not inheriting anything other than the Object class implicitly, this is not necessary. Intellisense didn't complain about or add it, why did you?
subaru_sti said:
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?
A bit off path, but getting there? :p
 
Thanks John. I have implemented all of your changes.

I have the following Structure for degrees as well:

VB.NET:
Public Structure Degrees
        Private _degrees As Double

        Public Sub New(ByVal degrees As Double)
            Me.Degrees = degrees
        End Sub

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

                _degrees = value
            End Set
        End Property
    End Structure

I call the structure like this:

VB.NET:
Dim myDegrees As New Degrees(degrees)

It is possible for "N/A" to be passed in for degrees as these values come from a web service. If there are no degrees, I need to pass something indicating that. What is the best way to handle this? The web service method currently accepts degrees as a string. If the value is not a string, N/A should be stored in the Structure.

Stephen
 
Longitude and latitude are both degree values, which is representable as Double data type. I don't see how 'n/a' can be a valid value. String to numeric data conversions usually belong in a Parse method.
 
You can always pass Nothing to your parameters, but you will have to protect any calculations trying to use Nothing as a value. Or make sure the value IsNot Nothing before calling it. Could this have been represented as a class?
VB.NET:
Public Structure Degrees
Private _degrees As Double
Public Sub New(ByVal degrees As Double)
     Me.Degrees = degrees '[FONT="Courier New"][COLOR="Red"]<-- shouldn't this be Me._degress = degrees[/COLOR][/FONT]
End Sub

Public Property Degrees() As Double '[FONT="Courier New"][COLOR="Red"]<-- property name the same as the structure name?[/COLOR][/FONT]
     Get
        Return _degrees
     End Get
     Set(ByVal value As Double)
        If value > 360 Then Throw New ArgumentOutOfRangeException("Degrees cannot be greater than 360.")
        If value < 0 Then Throw New ArgumentOutOfRangeException("Degrees cannot be less than 0.")

        _degrees = value
     End Set
     End Property
End Structure
 
Last edited:
You should forget that Degrees type. If you want N/A for a numeric type then you should make them nullable, i.e.
VB.NET:
Private number As Nullable(Of Double)
or the shorthand way:
VB.NET:
Private number As Double?
You can then assign Nothing to the variable and it will actually be Nothing rather than 0.0. You then use the variable's HasValue property to check whether it has a value and, if it does, you get it from the Value property:
VB.NET:
If number.HasValue Then
    MessageBox.Show(number.Value.ToString())
Else
    MessageBox.Show("No value")
End If
Obviously your property must be the nullable type too.
 
newguy said:
Public Sub New(ByVal degrees As Double)
Me.Degrees = degrees '<-- shouldn't this be Me._degress = degrees
One may want to use the existing validation logic present in property setters when getting input from constructor parameters or other places.
 
Hello and thanks for all of the help.

Just to answer a few questions first. John, Degrees can be N/A because if the GPS program cannot calculate the degrees, it passes something other than 0 to 360.

To set degrees as Nothing or Nullable, I need to first set the variable to a string so that I can pass in "N/A" or some numbers. How do I convert it to a double?

Stephen
 
Degrees can be N/A because if the GPS program cannot calculate the degrees
I disagree, I'd say this is a way to inform you that the returned data is not valid, in which case your Parse method should discard it and throw an exception, while the TryParse method should return False when value is not valid.
 
The return data is coming off of a GPS device. Sometimes, the device cannot calculate the degrees. If it can't, I still want the lat and long values sent to this web service with the degrees value being N/A or Nothing. If degrees is N/A, I can calculate it based on the current and previous lat/long values.

I will try out the TryParse.

Stephen
 
Okay, I think I've got it. How does this look:

VB.NET:
Dim degrees as string

' Could set degrees = "N/A" or "90"

Dim myDegrees As New Degrees()
Double.TryParse(degrees, myDegrees.DegreeValue)

If myDegrees.DegreeValue = Nothing Then
        Return "Invalid Number"
Else
        Return "Valid Number: " & myDegrees.DegreeValue.ToString
End If

VB.NET:
    Public Structure Degrees
        Private _degrees As Double

        Public Sub New(ByVal degrees As Double)
            Me.DegreeValue = degrees
        End Sub

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

                _degrees = value
            End Set
        End Property
    End Structure

Stephen
 
So is "degrees" here just a very bad name for direction/bearing? That would explain some of the previous confusion in this thread, and a Double value of direction in degrees would have to be Nullable to contain such no-range value, or a magic number like -1. This would have to be translated to appropriate strings when passing the data to the web service proxy classes. Are you sure the service haven't defined these types already?
 
The value gets passed in as a string between 0 and 360, or else N/A if it was not obtained. That is "degrees", isn't it? Or what else should I call it? I have another function that I wrote to convert the degree number to N, S, E, and W.

The web service hasn't defined these types yet because this is the web service.

Also, is there a built in function that checks if a value is equal to nothing and then lets you return another value if it is? It not, I'll just have to write one.

Thanks,

Stephen
 
subaru_sti said:
That is "degrees", isn't it? Or what else should I call it?
Longitude and latitude are also measured in degrees, you mean you should call every property that is a degree value for Degree? That would not make any sense. In this regard 'degree' is the TYPE of value, and type names are rarely good candidates for member names.
guidelines said:
Consider using names based on a parameter's meaning rather than names based on the parameter's type.
Also, is there a built in function that checks if a value is equal to nothing and then lets you return another value if it is?
Nullable Value Types
 
Thanks John.

I understand now. I have changed the class to "Direction" and the property and variables to "Course". Does that make more sense?

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

I don't know if Nullable Value Types is what I am looking for... I was wondering if there was a build in function that did this:

VB.NET:
        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

Stephen
 
Back
Top