VB: How do I create nested classes? - vb.net

I would like to write a nested class into an existing class of my own. But I can't find how because I have no idea how this is really called.
What do I mean by nested class? With a table dt from the DataTable class, I can write dt.Columns.add(). Columns would be property of the main class and add would be a method from a nested class.
Any suggestions?

That is not a nested class, it's simply a class. The Columns property is of the type DataColumnCollection that has a public method called Add. To build your own in a similar fashion it would simply be:
Public Class MyFirstClass
Public Sub New()
End Sub
Dim _second As New MySecondClass()
Public Property Second() As MySecondClass
Get
Return _second
End Get
Set(ByVal Value As MySecondClass)
_second = Value
End Set
End Property
End Class
Public Class MySecondClass
Public Sub New()
End Sub
Public Sub MySecondClassMethod()
'Do something
End Sub
End Class
This would then be called in some other class or functionality like:
Dim x as New MyFirstClass()
x.Second.MySecondClassMethod()

Related

VB.NET Trigger method from within a generic-list property when values change by using Add/Addrange/Remove, etc

How to call a method from within a property which is declared as a List(Of T), when new values were added into Property?
In my example you see a class called Something, another class called MyClass with a Property Things As List(Of Something), and my main form where a new instance of MyClassis made, then some values has been added into its' Things Property by using the Add (or AddRange) method of generic lists.
My question: how to trigger DoSomeAction() method every time Things property values change (added or removed by using Add, Addrange, Remove, etc. methods)?
Public Partial Class MainForm ' System.Windows.Forms.Form
Dim newMyClass As New MyClass
newMyClass.Things.Add(New Something())
newMyClass.Things.AddRange(New Something() {New Something(), New Something()})
End Class
Public Class MyClass
Private thingsValue As List(Of Something)
'
Public Property Things() As List(Of Something)
Set(value As List(Of Something))
thingsValue = value
DoSomeAction()
End Set
Get
Return thingsValue
End Get
End Property
'
Private Sub DoSomeAction()
'[inside method DoSomeAction()]
End Sub
'
Public Sub New()
thingsValue = New List(Of Something)
End Sub
End Class
Public Class Something
'[inside class Something]
End Class

VB.Net Make Inherited Overridable Method take different parameter

I have a situation in VB.Net where I have a variable that will be an instance of one of two classes, both derived from a parent class, but which class is determined at run time. To do this, I declare the variable as the parent class, then set it to one or the other child class based on a true/false value.
After that, I invoke the only public method (Main) for the child class, I want the parameter it takes be different based on which child class it is. However, I'm finding that I can't do this with an override or overload, at least as I understand them. Is there a way to do this?
I guess I could have Main1 and Main2 as inherited methods with the specific parameter type and invoke them conditionally as well, but just looking to see if I can keep it simple.
Here's a mock-up of what I'm trying to accomplish, which doesn't work:
Public Class ThisParam
End Class
Public Class Param1
Inherits ThisParam
End Class
Public Class Param2
Inherits ThisParam
End Class
Public Class ThisBase
Public Overridable Sub Main (X as ThisParam)
'Empty for inheritance
End Sub
End Class
Public Class Child1
Inherits ThisBase
Public Overrides Sub Main(X as Param1)
'Do Stuff
End Sub
End Class
Public Class Child2
Inherits ThisBase
Public Overrides Sub Main(X as Param2)
'Do Stuff
End Sub
End Class
Dim MyObject As ThisBase
Dim MyParam as ThisParam
If True then MyObject = New Child1 Else MyObject = New Child2 End If
If True then MyParam = New Param1 Else MyParam = New Param2 End If
MyObject.Main(MyParam)

Best way to expose an object with read-only properties only

I can't find an answer to my question so I'm asking a new one.
I have an object where I want to fill it's properties from another class in the same solution. But the object should expose read-only properties only so the outside-caller can't see nor access the setter (cause there is no setter).
What is the best way to fill the internal backing variables from the same solution? I know I could do it in the constructor but I want to be able to set the variables after creating the object.
Sorry for my weird explaination, maybe a bit of code could help.
This is what I'm doing now:
Public Class ReadonlyObject
Protected Friend Sub New()
End Sub
'Could use this, but don't want to...
Protected Friend Sub New(foo As String)
End Sub
Friend _foo As String
Public ReadOnly Property Foo As String
Get
Return _foo
End Get
End Property
End Class
Public Class FillReadonlyObject
Private Sub DoSomeHeavyWork()
Dim roObject As New ReadonlyObject
roObject._foo = "bar"
'Could use this, but don't want to...want to access properties directly.
Dim roObject2 As New ReadonlyObject("bar")
End Sub
End Class
With this, the ReadonlyObject's properties are correctly exposed as readonly but I'm afraid it's bad practice.
I've seen implementations like this:
Public Class ReadonlyObject
Protected Friend Sub New()
End Sub
Private _foo As String
Public Property Foo As String
Get
Return _foo
End Get
Friend Set(value As String)
_foo = value
End Set
End Property
End Class
Public Class FillReadonlyObject
Private Sub DoSomeHeavyWork()
Dim roObject As New ReadonlyObject
roObject.Foo = "bar"
End Sub
End Class
This works, but exposes the property with a setter. It's not accessible, but it's visible and I don't want that :)
So maybe it's only a cosmetic thing but I think it's nice to tell the caller (or at least intellisense) the property is strictly read-only.
Thanks, Jan
If you want to explicitly declare the property as read-only, but then still have a way to set it after it is constructed, then all you need to do is create your own setter method rather than using the one automatically created for you but the property. For instance:
Public Class ReadonlyObject
Protected Friend Sub New()
End Sub
Private _foo As String
Public ReadOnly Property Foo As String
Get
Return _foo
End Get
End Property
Friend Sub SetFoo(value As String)
_foo = value
End Sub
End Class
Public Class FillReadonlyObject
Private Sub DoSomeHeavyWork()
Dim roObject As New ReadonlyObject
roObject.SetFoo("bar")
End Sub
End Class
Or, you could create two properties, like this:
Public Class ReadonlyObject
Protected Friend Sub New()
End Sub
Public ReadOnly Property Foo As String
Get
Return HiddenFoo
End Get
End Property
Friend Property HiddenFoo As String
End Class
Public Class FillReadonlyObject
Private Sub DoSomeHeavyWork()
Dim roObject As New ReadonlyObject
roObject.HiddenFoo = "bar"
End Sub
End Class

how to access class from inherited class

I have two classes:
class class2
inherits class1
public sub modify()
'modify property of class1
end sub
end class
How can I modify class1 in a sub in class2?
You just call it. Example:
Public Class class1
Private _Value As String = String.Empty
Property Value() As String
Get
Return _Value
End Get
Set(ByVal value As String)
_Value = value
End Set
End Property
End Class
Public Class class2
Inherits class1
Public Sub modify()
Value = "modified"
End Sub
End Class
And to show it works:
Dim c2 As New class2
c2.modify()
MessageBox.Show(c2.Value)
You are asking about properties, note that only protected and public properties are visible to inherited classes.
You need the MyBase keyword when you are overriding an existing function in the parent class. Other protected or public properties or functions can be accessed regulary without any special keyword.
One tip I wanted to add to the above comments regarding accessing base class info is where you have a base class without a default contructor or want to use a specific constructor This is a good opportunity to use Mybase. You have to call the constructor before any additional actions take place in this scenario.
Public Class MyClass
Inherits baseClass
Public Sub New()
mybase.new("Oranges")
End Sub
End Class
Public Class baseClass
Private _someVariable as String
Public Sub New(byval passedString as string)
_someVariable = passedString
End Sub
End Class

What happens if a base method calls an overridden method in VB?

Consider the following example:
Public Class ParentClass
Public Sub GenerateReport
Dim Col As Collection
Col = GetItemCollection()
End Sub
Public Overridable Function GetItemCollection() As Collection
GetItemCollection = New Collection
GetItemCollection.Add("1")
GetItemCollection.Add("2")
GetItemCollection.Add("3")
End Function
End Class
Public Class ExtendedClass
Inherits ParentClass
Public Overrides Function GetItemCollection() As Collection
GetItemCollection = New Collection
GetItemCollection.Add("A")
GetItemCollection.Add("B")
GetItemCollection.Add("C")
End Function
End Class
Public Sub Main()
Dim cls As New ExtendedClass
cls.GenerateReport()
End Sub
When Main() calls cls.GenerateReport(), is the variable Col going to be a collection of numbers or letters? I'm hoping that it will recognize that cls is an instance of ExtendedClass and call the overridden method and return the letters.
It will be a collection of letters as you did override the method. However, where did you declare the GetItemCollection? You still need an instance variable.