Create triggers related to variables - vb.net

I have a class that looks like this:
Public Class LumberPiece
Public boardLength As Double
Public currentLeftEndPosition As Double
Public currentRightEndPosition As Double
Public Sub New(ByVal bl As Double, ByVal clp As Double)
boardLength = clsDimension.ConvertInchesToMillimeters(bl)
currentLeftEndPosition = clsDimension.ConvertInchesToMillimeters(clp)
currentRightEndPosition = clsDimension.ConvertInchesToMillimeters(clp + bl)
End Sub
End Class
I want to somehow have a trigger that calculates the currentRightEndPosition everytime that the currentLeftEndPosition is changed (rightEnd always equals leftend+ boardLength).
how can I do this?

You can do this using properties. By making the fields properties, you can control what happens when the property values are read and when they are set. For instance:
Public Class LumberPiece
Public Property BoardLength As Double
Public Property CurrentLeftEndPosition As Double
Get
Return _currentLeftEndPosition
End Get
Set(value As Double)
_currentLeftEndPosition = value
CurrentRightEndPosition = clsDimension.ConvertInchesToMillimeters(_currentLeftEndPosition + BoardLength)
End Set
End Property
Private _currentLeftEndPosition As Double
Public Property CurrentRightEndPosition As Double
Public Sub New(ByVal bl As Double, ByVal clp As Double)
BoardLength = clsDimension.ConvertInchesToMillimeters(bl)
CurrentLeftEndPosition = clsDimension.ConvertInchesToMillimeters(clp)
End Sub
End Class
Alternatively, you could choose to calculate the field every time it is accessed:
Public Class LumberPiece
Public Property BoardLength As Double
Public Property CurrentLeftEndPosition As Double
Public ReadOnly Property CurrentRightEndPosition As Double
Get
Return clsDimension.ConvertInchesToMillimeters(CurrentLeftEndPosition + BoardLength)
End Get
End Property
Public Sub New(ByVal bl As Double, ByVal clp As Double)
BoardLength = clsDimension.ConvertInchesToMillimeters(bl)
CurrentLeftEndPosition = clsDimension.ConvertInchesToMillimeters(clp)
End Sub
End Class

Related

How do I construct an "Add" routine for a custom object list?

I feel really stupid asking this question, but here goes...
I'm trying to create a custom object in VB, that is itself a list (or collection, or "tuple" - I'm not sure what the difference between these is) of custom objects, and I need to create routines to add and remove these secondary objects to/from the larger custom object. So far, my code goes something like this:
Public Class parameterSet
Friend _xParameter As String
Public Property xParameter() As String
Get
Return _xParameter
End Get
Set(value As String)
_xParameter = value
End Set
End Property
Friend _yParameter As String
Public Property yParameter() As String
Get
Return _yParameter
End Get
Set(value As String)
_yParameter = value
End Set
End Property
Friend _zParameter As String
Public Property zParameter() As String
Get
Return _zParameter
End Get
Set(value As String)
_zParameter = value
End Set
End Property
Public Sub New(ByVal xParameter As String, ByVal yParameter As String, ByVal zParameter As String)
_xParameter = xParameter
_yParameter = yParameter
_zParameter = zParameter
End Sub
End Class
Public Class parameterCollection
Friend _parameterCollection As New List(Of parameterSet)
Friend Sub Add(xParameter As String, yParameter As String, zParameter As String)
Throw New NotImplementedException()
End Sub
End Class
What do I have to put in the Add routine to make this work?
Your first class ought to look like this:
Public Class ParameterSet
Public Property X As String
Public Property Y As String
Public Property Z As String
Public Sub New(x As String, y As String, z As String)
Me.X = x
Me.Y = y
Me.Z = z
End Sub
End Class
Your second class ought to look like this:
Imports System.Collections.ObjectModel
Public Class ParameterSetCollection
Inherits Collection(Of ParameterSet)
Public Overloads Sub Add(x As String, y As String, z As String)
Add(New ParameterSet(x, y, z))
End Sub
End Class
You might even want to do this:
Imports System.Collections.ObjectModel
Public Class ParameterSetCollection
Inherits Collection(Of ParameterSet)
Public Overloads Function Add(x As String, y As String, z As String) As ParameterSet
Dim item = New ParameterSet(x, y, z)
Add(item)
Return item
End Function
End Class
The Collection(Of T) class already provides all the standard collection functionality and you can extend it as required.

How to determine why my code is not working?

Imports Kerry_Sales_Project
' base class
Public Class Bonus
Public Property SalesId As String
Public Property Sales As Double
' default constructor
Public Sub New()
_SalesId = String.Empty
_Sales = 0
End Sub
' parameterized constructor
Public Sub New(ByVal strId As String, ByVal dblSold As Double)
SalesId = strId
Sales = dblSold
End Sub
' GetBonus method
Public Overridable Function GetBonus() As Double
Return _Sales * 0.05
End Function
Public Shared Widening Operator CType(v As PremiumBonus) As Bonus
Throw New NotImplementedException()
End Operator
End Class
' derived class
Public Class PremiumBonus
Public Property Sales As Double
Public Property strId As String
' default constructor
Public Sub New(strId As String)
MyBase.New()
End Sub
' parameterized constructor
Public Sub New(ByVal strId As String, ByVal dblSold As Double)
MyBase.New(strId, dblSold)
End Sub
' class method
Public Overrides Function GetBonus() As Double
Return MyBase.GetBonus() + (Sales - 2500) * 0.01
End Function
End Class
In effect, you forgot to place Inherits Bonus in the Premium Bonus class. It would be something like
Public Class PremiumBonus: Inherits Bonus
And the other thing is the CType operator overload.
Public Shared Widening Operator CType(v As PremiumBonus) As Bonus
Throw New NotImplementedException()
End Operator
This operator overload is not necessary because the PremiumBonus class is a child of Bunus and they are contained.

Advantage or Disadvantage between Two Class Modules

What would be the advantages or disadvantages of using Class1 instead of Class2?
The quantity information stored in each instance of the class will be adjusted up and down as needed (via the functions, and while it seems to make sense to me that I would only need to make these variables public so that they are visible from outside the class, I feel that there is most likely some reason that this shouldn't been done.
Class1
Option Explicit
Public Sequence As String
Public Quantity As Double
Public Sub AddQty(sAddQty As Double)
Quantity = Quantity + AddQty
End Sub
Public Sub SubQty(sSubQty As Double)
Quantity = Quantity - sSubQty
End Sub
Class2
Option Explicit
Private iSeq As String
Private iQty As Double
Public Property Get Qty() As Double
Qty = iQty
End Property
Public Property Let Qty(lQty As Double)
iQty = lQty
End Property
Public Property Get Sequence() As String
Sequence = iSeq
End Property
Public Property Let Sequence(lSeq As String)
iSeq = lSeq
End Property
Public Sub AddQty(sAddQty As Double)
iQty = iQty + AddQty
End Sub
Public Sub SubQty(sSubQty As Double)
iQty = iQty - sSubQty
End Sub
In terms of interfaces, the two are exactly equivalent, because public fields are exposed as Property members. If you added a 3rd class module and wrote this:
Implements Class1
You would be forced by the compiler to add these members:
Private Property Get Class1_Sequence() As String
End Property
Private Property Let Class1_Sequence(ByVal RHS As String)
End Property
Private Property Get Class1_Quantity() As Double
End Property
Private Property Let Class1_Quantity(ByVal RHS As Double)
End Property
Private Sub Class1_AddQty(sAddQty As Double)
End Sub
Private Sub Class1_SubQty(sSubQty As Double)
End Sub
If you added another class module and wrote this:
Implements Class2
You would be forced by the compiler to have essentially the exact same members:
Private Property Get Class2_Sequence() As String
End Property
Private Property Let Class2_Sequence(ByVal RHS As String)
End Property
Private Property Get Class2_Qty() As Double
End Property
Private Property Let Class2_Qty(ByVal RHS As Double)
End Property
Private Sub Class2_AddQty(sAddQty As Double)
End Sub
Private Sub Class2_SubQty(sSubQty As Double)
End Sub
When properties do nothing and there's no incentive to properly encapsulate their values, go ahead and have public fields.
However there's little need for AddQty or SubQty instance methods when the backing field exposes a Property Let accessor - one could simply do foo.Quantity = foo.Quantity + 2 instead. An API that appears to provide multiple ways to do the same thing, is a confusing API.
So what you do, is you define an explicit interface that defines the API you want to work with:
Public Property Get Quantity() As Double
End Property
Public Property Get Sequence() As String
End Property
Public Sub AddQty(ByVal value As Double)
End Sub
Public Sub SubQty(ByVal value As Double)
End Sub
And then make your class Implements this interface (say, ISomething), and the rest of the code works with this ISomething interface that only exposes the members you want it to be able to work with - and that excludes the class' Property Let members; the rest of the code only sees what it needs to see, and can only access what it needs to access.
Dim foo As ISomething
Set foo = New Something
'foo.Quantity = 42 ' illegal
Dim bar As Something
Set bar = foo
bar.Quantity = 42 ' ok
bar.AddQty 2
Debug.Print foo.Quantity ' should be 44

How Do I Create an Extension of a Single Class Property

I have a primitive Class that looks like this:
Public Class BaseGeoData
Property GeoOrigin As String
Property GeoDestination As String
Property TravelDistance As Double?
Property TravelTime As Double?
Public Sub New()
End Sub
End Class
Public Class GeoData
Inherits BaseGeoData
Public Sub New(geoOrigStr As String, geoDestStr As String)
GeoOrigin = geoOrigStr
GeoDestination = geoDestStr
TravelDistance = 5000 'in meters
TravelTime = 360 'in minutes
End Sub
End Class
I want to be able to add 2 extensions that will return converted values like this:
TravelDistance.ToMiles()
TravelTime.ToHours()
When I add a Module to extend the class, it offers the extension to the entire class, most properties of which will never use the extension. How can I just offer the extensions to the properties that need them?
Introduce own type of "Unit" for measurement values
Public MustInherit Class Unit
Public ReadOnly Property Value As Double
Public MustOverride ReadOnly Property Name As String
Public Sub New(value As Double)
Me.Value = value
End Sub
Public Overrides Function ToString() As String
Return $"{Value} {Name}"
End Function
End Class
Public Class Meter
Inherits Unit
Public Sub New(value As Double)
MyBase.New(value)
End Sub
Public Overrides ReadOnly Property Name As String
Get
Return "m"
End Get
End Property
End Class
Public Class Mile
Inherits Unit
Public Sub New(value As Double)
MyBase.New(value)
End Sub
Public Overrides ReadOnly Property Name As String
Get
Return "mi"
End Get
End Property
End Class
And extension methods for creating unit and convertions
Public Module UnitConversions
<Extension>
Public Function Meters(value As Integer) As Meter
Return New Meter(value)
End Function
<Extension>
Public Function Miles(value As Integer) As Mile
Return New Mile(value)
End Function
<Extension>
Public Function ToMiles(meters As Meter) As Mile
Dim miles = meters.Value * 0.00062137
Return New Mile(miles)
End Function
<Extension>
Public Function ToMeters(miles As Mile) As Meter
Dim meters = miles.Value * 1609.344
Return New Meter(meters)
End Function
End Module
Then you can use value in more readable manner
TravelDistance = 5000.Meters() ' meters
' Conversion
geoData.TravelDistance.ToMiles() ' miles
Console.WriteLine(geoData.TravelDistance) ' print 3.10685 mi
You can only add extension methods into types (i.e. classes).
TravelDistance is of type Double? so you have to add an extention method into Double?.
Note that it would make the method available for every Double?, which may not be something you want.
I really like Plutonix's resolution and is the same one I would go for first.
Its simple and resolves your initial problem.
Public Class BaseGeoData
Property GeoOrigin As String
Property GeoDestination As String
Property TravelDistance As Double?
Property TravelTime As Double?
Public Sub New()
End Sub
End Class
Public Class GeoData
Inherits BaseGeoData
Public Sub New(geoOrigStr As String, geoDestStr As String)
GeoOrigin = geoOrigStr
GeoDestination = geoDestStr
TravelDistance = 5000 'in meters
TravelTime = 360 'in minutes
End Sub
Function DistanceMiles() As Double
DistanceMiles = (TravelDistance/1609.344)
End Function
Function TimeHours() As Double
DistanceMiles = (TravelTime /60)
End Function
End Class

Call Base functions from Child in VB.net

How to call the base functions in vb.net?
Imports System.Data.Sql
Imports System.Data.SqlClient
Public Class Box
Public length As Double ' Length of a box
Public breadth As Double ' Breadth of a box
Public height As Double ' Height of a box
Public function setLength(ByVal len As Double)
length = len
End Sub
Public Sub setBreadth(ByVal bre As Double)
breadth = bre
End Sub
Public Sub setHeight(ByVal hei As Double)
height = hei
End Sub
Public Function getVolume() As Double
Return length * breadth * height
End Function
End Class
It says syntax error when I use MyBase to call the base functions
Public Class myChild : Inherits Box
'box 1 specification
MyBase.setLength(6.0)
MyBase.setBreadth(7.0)
MyBase.setHeight(5.0)
'box 2 specification
MyBase.setLength(12.0)
MyBase.setBreadth(13.0)
MyBase.setHeight(10.0)
'volume of box 1
volume = MyBase.getVolume()
Console.WriteLine("Volume of Box1 : {0}", volume)
'volume of box 2
volume = MyBase.getVolume()
End Class
You can't call MyBase from there as the object hasn't yet been constructed.
A better implementation would be:
Box.vb
Public Class Box
Private mLength As Double ' Length of a box
Private mBreadth As Double ' Breadth of a box
Private mHeight As Double ' Height of a box
Public Sub New(ByVal length As Double, ByVal breadth As Double, ByVal height As Double)
Me.mLength = length
Me.mBreadth = breadth
Me.mHeight = height
End Sub
Public Property Length As Double
Get
Return Me.mLength
End Get
Set(ByVal value As Double)
Me.mLength = value
End Set
End Property
Public Property Breadth As Double
Get
Return Me.mBreadth
End Get
Set(ByVal value As Double)
Me.mBreadth = value
End Set
End Property
Public Property Height As Double
Get
Return Me.mHeight
End Get
Set(ByVal value As Double)
Me.mHeight = value
End Set
End Property
Public Function getVolume() As Double
Return Length * Breadth * Height
End Function
End Class
Child.vb
Public Class Child : Inherits Box
Public Sub New(ByVal length As Double, ByVal breadth As Double, ByVal height As Double)
MyBase.New(length, breadth, height)
End Sub
End Class
Example
Sub Main()
Dim box1 As New Child(6.0, 7.0, 5.0)
Dim box2 As New Child(12.0, 13.0, 10.0)
Console.WriteLine("box1 volume is: {0}", box1.getVolume())
Console.WriteLine("box2 volume is: {0}", box2.getVolume())
End Sub