Returning the self type in Mustinherit class - VB.NET - vb.net

I have an abstract class as
Public MustInherit Class GenericClass
Public Sub New(Byval x as Integer)
' Some code here
End Sub
End Class
I inherit this class to another class as follows:
Public Class SpecificClass
Inherits GenericClass
Public Sub New(Byval x as Integer)
MyBase.New(x)
End Sub
End Class
I want to add a Shared Function e.g. magicFunction in such a way that when I use it, it should return an object of type SpecificClass. What should I do?
I want something like this but it is not allowed in VB.NET
Public MustInherit Class GenericClass
Public Sub New(Byval x as Integer)
' Some code here
End Sub
Public Shared Function magicFunction(Byval y as Integer) as GenericClass
Dim z as Integer
' Some code here that will alter the value of z
Return New GenericClass(z) ' Not allowed in VB.NET -- MustInherit class cannot have new
End Sub
End Class
Calling the magicFunction of the inheriting SpecificClass should return an object of SpecificClass like this:
Public Class ABC
Public Function myAwesomeFunction as SpecificClass
Dim objSpecificClass as SpecificClass
objSpecificClass = SpecificClass.magicFunction(someInteger)
Return objSpecificClass
End Sub
End Class
Any help would be appreciated

This may help:
Public MustInherit Class GenericClass(Of T As {GenericClass(Of T)})
Public Sub New(ByVal x As Integer)
' Some code here
End Sub
Public Shared Function magicFunction(ByVal y As Integer) As GenericClass(Of T)
Dim z As Integer
' Some code here that will alter the value of z
Return Activator.CreateInstance(GetType(T), z)
End Function
End Class
Public Class SpecificClass1
Inherits GenericClass(Of SpecificClass1)
Public Sub New(ByVal x As Integer)
MyBase.New(x)
End Sub
End Class
Public Class SpecificClass2
Inherits GenericClass(Of SpecificClass2)
Public Sub New(ByVal x As Integer)
MyBase.New(x)
End Sub
End Class
Usage:
Dim a As SpecificClass1 = SpecificClass1.magicFunction(1)
Dim b As SpecificClass2 = SpecificClass2.magicFunction(2)

Related

how to dont call contruvtor Inherits in vb

I want to call Dim objFkkiNinteiJokyoRpt As New A(objCsv) in class C. But class A Inherits Common. If now call contructor will An error occurred.Because type Object C.CsvGenerator diference type Object in common. I thnk now stop call to contructor common (or any other way) but i dont know how to do. Helf me please. Sorry because my english so bad
Public Class A Inherits Common
Public _objCsv As C.CsvGenerator
Friend Sub New(ByVal objCsv As C.CsvGenerator)
_objCsv = objCsvGenerator
End Sub
Public Sub New()
End Sub
End Sub
Public Sub New(ByVal objRSReportObj As Object)
MyBase.New(objRSReportObj)
InitializeReport()
End Sub
End Class
Public Class C
Private Function SelectCSV
Dim objCsv As New CsvGenerator("")
Dim objFkkiNinteiJokyoRpt As New A(objCsv)
End Function
Friend Class CsvGenerator
Inherits cmShare.cmObject
End Class
End Class
Public Class Common
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal objRSReport As Object)
MyBase.New(objRSReport)
End Sub
End Class

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.

Implement same logic for diffrent objects as T

I suppose to use T but i am not sure how do it in proper way.
Let's consider following example.
Base class:
Public Class HtmlBase
Implements IGetInformation
Public Overridable Function IsExist() As Boolean Implements IGetInformation.IsExist
Throw New NotImplementedException()
End Function
Public Overridable Function GetIdByName(pName As String) As Integer Implements IGetInformation.GetIdByName
Throw New NotImplementedException()
End Function
End Class
Example classes which inherit from base class:
Public Class HtmlSubSection
Inherits HtmlBase
'--sometimes i have to overload to add additioinal parameter
Public Overloads Function isExist(subsection As String) As Boolean
Dim dlsubkategorie As New DataLayer.DALSubSection
Return dlsubkategorie.CheckIfSubSectionExist(subsection)
End Function
Public Overrides Function GetIdByName(subsectionName As String) As Integer
Dim dlget As New DataLayer.DALSubSection
Return dlget.GetSubSectionIdByName(subsectionName)
End Function
End Class
Public Class HtmlSection
Inherits HtmlBase
'sometime i have to overload to add additioinal parameter
Public Overloads Function IsExist(section As String) As Boolean
Dim dlsubkategorie As New DataLayer.DALSection
Return dlsubkategorie.CheckIfSectionExist(section)
End Function
Public Overrides Function GetIdByName(Name As String) As Integer
Dim dlsubkategorie As New DataLayer.DALSection
Return dlsubkategorie.GetSectionIdByName(Name)
End Function
End Class
As could be seen above two classes which inherits from base within their methods has same logic (sometimes i have to use additional parameter therefore overloads there, but are using diffrent DAL class to call. I would like to implement this logic in base class and for each just point to specific DAL. How to do that to not everytime in those classes write e.g:
Dim dlsubkategorie As New DataLayer.<DALSection>
Return dlsubkategorie.GetSectionIdByName(Name)
EDIT:
Htmlbase constructor's:
Sub New()
End Sub
Sub New(pId As Integer)
_Id = pId
End Sub
HtmlSubSection's constructors:
Sub New()
MyBase.New()
AvailableSentences = New List(Of HtmlSubSection_Sentence)
SelectedSentences = New List(Of HtmlSubSection_Sentence)
End Sub
Sub New(pId As Integer)
MyBase.New(pId)
End Sub
Sub New(pName As String)
_Name = pName
End Sub
Sub New(pId As Integer, pName As String)
MyBase.New(pId)
_Name = pName
End Sub
HtmlSection's constructors:
Sub New()
MyBase.New()
End Sub
Sub New(pId As Integer)
MyBase.New(pId)
End Sub
Sub New(pId As Integer, pName As String, pPosition As Integer)
MyBase.New(pId)
_Name = pName
_Position = pPosition
End Sub
Sub New(pName As String)
_Name = pName
End Sub
Sub New(pName As String, pPosition As Integer)
_Name = pName
_Position = pPosition
End Sub
You donĀ“t need generic types here. Just use Interfaces, Sub Classing and Polymorphism correctly.
New Interface IDAL which is implemented by DAL classes to get rid of different method names which take same parameters and do the same:
Public Interface IDAL
Function CheckIfSectionExist(section As string) As Boolean
Function GetSectionIdByName(section As string) As Integer
End Interface
Public Class DALSection
Implements IDAL
Public Function CheckIfSectionExist(section As string) As Boolean Implements IDAL.CheckIfSectionExist
...
End Function
Public Function GetSectionIdByName(section As String) As Integer Implements IDAL.GetSectionIdByName
...
End Function
End Class
Public Class DALSubSection
Implements IDAL
Public Function CheckIfSubSectionExist(subSection As string) As Boolean Implements IDAL.CheckIfSectionExist
...
End Function
Public Function GetSubSectionIdByName(subSection As String) As Integer Implements IDAL.GetSectionIdByName
...
End Function
End Class
Base class changed to abstract and the constructor now takes IDAL parameter. Function can now be executed polymorphic. Added a isExists(string) function to avoid overloading:
Public MustInherit Class HtmlBase
Implements IGetInformation
Public Property DAL as DataLayer.IDAL
Protected Sub New(dal as DataLayer.IDAL)
Me.DAL = dal
End Sub
Public Overridable Function isExist() As Boolean Implements IGetInformation.isExist
Return True
End Function
Public Overridable Function isExist(section As String) As Boolean
Return DAL.CheckIfSectionExist(Section)
End Function
Public Overridable Function GetIdByName(pName As String) As Integer Implements IGetInformation.GetIdByName
Return DAL.GetSectionIdByName(pName)
End Function
End Class
Client classes only need to give correct DAL to base class:
Public Class HtmlSubSection
Inherits HtmlBase
Public Sub New()
MyBase.New(New DataLayer.DALSubSection)
End Sub
End Class
Public Class HtmlSection
Inherits HtmlBase
Public Sub New()
MyBase.New(New DataLayer.DALSection)
End Sub
End Class
Basically it would be ideal if IGetInformation had a isExist method with an optional string parameter. This would save one unneccessary method in HtmlBase.

VB redeclare as different type

Can I change the variable type by declare it again in the code. Like...
Dim x As New DEV_CLASS
If environment = "UAT" Then
Dim x As New UAT_CLASS
End If
x.something1
x.something2
x.something3
As #TyCobb pointed out, use an interface
Dim x As MyInterface
If environment = "UAT" Then
x = New UAT_CLASS
Else
x = New DEV_CLASS
'DirectCast(x, DEV_CLASS).SomeOtherDevMethod()
End If
x.Method1()
x.Method2()
Class and interface definition:
Public Interface MyInterface
Sub Method1()
Sub Method2()
End Interface
Public Class DEV_CLASS
Implements MyInterface
Public Sub Method1() Implements MyInterface.Method1
End Sub
Public Sub Method2() Implements MyInterface.Method2
End Sub
Public Sub SomeOtherDevMethod()
End Sub
End Class
Public Class UAT_CLASS
Implements MyInterface
Public Sub Method1() Implements MyInterface.Method1
End Sub
Public Sub Method2() Implements MyInterface.Method2
End Sub
End Class

Incompatible interface

Please see the code below:
Public Class clsCar
Implements IVehicle
Public Function getWheels() As Integer Implements IVehicle.getWheels
Return 4
End Function
End Class
Public Interface IVehicle
Function getWheels() As Integer
End Interface
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim list As List(Of IVehicle) = New List(Of IVehicle)
Dim v1 As IVehicle = New clsCar
Dim v2 As IVehicle = New clsBus
list.Add(v1)
list.Add(v2)
Dim IVehicle As IVehicle = New clsCar
Dim IVehicle2 As IVehicle = New clsBus
For Each IVehicle In list
MsgBox(IVehicle.getWheels())
Next
End Sub
End Class
I want to add a new function to the clsBus class:
Public Function getWheels(ByVal strCarType As String) As Integer
If strCarType = "Robin Ryliant" Then
Return 3
Else
Return 4
End If
End Function
How do I call this from the FOR EACH statement? At the moment it will call getWheels with no arguments.
You will have to add the method overload to the interface in order to be able to call it from a IVehicle variable.
Public Interface IVehicle
Function getWheels() As Integer
Function getWheels(ByVal strCarType As String) As Integer
End Interface
But probably it is better to have different, more specialized car types
Public Class clsCar
Implements IVehicle
Public Overridable Function getWheels() As Integer Implements IVehicle.getWheels
Return 4
End Function
End Class
Public Class clsRobinRyliantCar
Inherits clsCar
Public Overrides Function getWheels() As Integer
Return 3
End Function
End Class
This does not break the inheritance hierarchy and is purely polymorphic.
I think I would go for something more like this, with the number of wheels being an instance property (code in LINQPad format):
Sub Main
Dim list As List(Of IVehicle) = New List(Of IVehicle)()
list.Add(New clsCar("Ford Focus", 4))
list.Add(New clsCar("Robin Ryliant", 3))
list.Add(New clsBus())
For Each v In list
Console.WriteLine(String.Format("{0}:{1}", v.GetVehicleType(), v.GetWheels()))
Next
End Sub
' Define other methods and classes here
Public Interface IVehicle
Function GetVehicleType() As String
Function GetWheels() As Integer
End Interface
Public MustInherit Class clsVehicle
Implements IVehicle
Protected Property VehicleType As String
Protected Property Wheels As Integer
Protected Sub New(vehicleType As String, wheels As Integer)
Me.VehicleType = vehicleType
Me.Wheels = wheels
End Sub
Public Function GetVehicleType() As String Implements IVehicle.GetVehicleType
Return Me.VehicleType
End Function
Public Function GetWheels() As Integer Implements IVehicle.GetWheels
Return Me.Wheels
End Function
End Class
Public Class clsCar
Inherits clsVehicle
Public Sub New(vehicleType As String, wheels As Integer)
MyBase.New(vehicleType, wheels)
End Sub
End Class
Public Class clsBus
Inherits clsVehicle
Public Sub New()
MyBase.New("Bus", 4)
End Sub
End Class
If your clsBus and clsCar are meant to refer to a specific car then the type should be a member of that class already, not something you pass in when you want to get information. To this end I'd suggest that you have "type" as something you can pass in the constructor and then the method on the bus would have no parameters and would just refer to its internal type to determine how many wheels it has.
I'm not too fluent with VB.NET so would probably make mistakes in example code but hopefully you get what I mean. If not I'll knock up some code. :)