Call baseclass property - vb.net

It's rather a simple question and both will work. But I'm just wondering what the best practice is. When a child class changes a variable in the baseclass. Should it call the property or just change the underlying variable.
I'm not using the property to do something with the data. The code in the child class is the same. But what is considered the best practice OOP wise?
Sample code:
Public Class TestDirect
Protected temp As Integer
End Class
Public Class TestChldDirect
Inherits TestDirect
Public Sub New()
MyBase.temp = 1
End Sub
End Class
versus
Public Class TestProperty
Private _temp As Integer
'
Public Property temp() As Integer
Get
Return Me._temp
End Get
Set(ByVal value As Integer)
Me._temp = value
End Set
End Property
End Class
Public Class TestChldProperty
Inherits TestProperty
Public Sub New()
MyBase.temp = 1
End Sub
End Class

The second approach gives you more flexibility later on and better protects/hides your underlying implementation. For instance, in your example you might want to modify the type of temp, add some validation etc. Those changes would be more difficult in your first example as you would be affecting the classes that derive from your base class. In the second example you can make the change without affecting any derived classes.

Related

Is there a keyword that can make a class variable readonly from outside the class but not on the inside?

Basically, the readonly keyword doesn't let me modify a field after I first create the class instance. I could use a property but in this case its just extra overhead. Is there a keyword to make a class field readonly from only outside the class?
make the field private, provide getter and setter for it.
Make the setter private.
This way the value can be seen from outside the class by the getter,but, cannot be set/written from outside the class.
this makes the property read-only from outside the class.
As others have stated, use a property. If you don't want to split the property into one Getter and one Setter then make the setter private.
Public Class Foo
Public Property Abc() As Object
Get
Return Me.m_Abc
End Get
Private Set(value As Object)
Me.m_Abc = value
End Set
End Property
Private m_Abc As Object
End Class
However: The common way is to set the access level of the field to Friend making it accessible within the same assembly, but not from outside the assembly.
Public Class Foo
Public ReadOnly Property Abc() As Object
Get
Return Me.m_Abc
End Get
End Property
Friend m_Abc As Object
End Class
No there isn't. This type is scenario is precisely why properties are provided in the first place. You get a whole lot of flexibility.
However, if you insist you want to use a read only field, you can use reflection to change the value:-
Public Class TestClass
Public ReadOnly MyNumber As Integer
Public Sub New()
'Readonly fields can only be changed this way
'in the constructor
Me.MyNumber = 900
End Sub
Public Sub ChangeNumber(ByVal num As Integer)
SetNumber(num)
End Sub
Private Sub SetNumber(ByVal num As Integer)
Dim fi = Me.GetType.GetField("MyNumber")
'Reflection can change the value of
'a read only field after construction
fi.SetValue(Me, num)
End Sub
End Class
Note that this is a very terrible thing. Reflection shouldn't be used for this sort of thing as you're going to take a performance hit. Just use properties and save yourself the trouble.

VB.NET constructors in derived classes

I have a base class that I use with reflection to fill the fields of the derived classes, reading from the database.
Public MustInherit Class DaoBase : Implements IEquatable(Of DaoBase)
Sub New()
' Empty, hate to have it
End Sub
Sub New(reader As DbDataReader)
' Reads the DB and fills the instance fields
End Sub
' More stuff...
End Class
The derived classes usually have a non-default constructor to set its fields:
Public Class Customer
Inherits DaoBase
Public Sub New(
id As Integer,
description As String)
Me.id = id
Me.description = description
End Sub
End Class
Questions:
1) I don't like to have the empty constructor in the base class. It sits there unused and could create an object in an incorrect state. If I remove it, then the compiler gives an error because, missing the default constructor, the derived class constructor should call the only-one base class constructor.
2) I can't do new Customer(myReader) because that constructor is not in the derived class, even if it's in the base class. I have to explicitly declare it, which I don't like.
Public Class Customer
Inherits DaoBase
Public Sub New(
id As Integer,
description As String)
Me.id = id
Me.description = description
End Sub
Public Sub New(reader As DbDataReader)
MyBase.New(reader)
End Sub
End Class
If your base class is filling fields in the derived class, it sounds like you should be using an interface instead of what you're doing.
As for your questions, just because you don't like it doesn't make it wrong. But as one comment said, if you change the second New to:
Sub New(Optional reader as DbDataReader = Nothing)
then you fulfill the requirement to have an empty constructor and you can have it do the right thing when no reader is given.

How to use classes as properties only?

I have been trying to do this for a long time but I can't find anything anywhere. I think I am not searching it as it should...
A little example:
Class MainClass
Property ExampleProperty As New ExamplePropertyClass
Private Class ExamplePropertyClass
Sub DoSomething()
End Sub
End Class
End Class
In the previous code the ExamplePropertyClass is used as an property of the MainClass.
There is always an error that says I can't expose a private class as propery.
But how is it possible to make only the property "Visible", I mean The user who is going to use the code should only use the property and not the class, how can the class be not inherited or visible?
What is property actually syntactic sugar for setter and getter.So mostly it is default public
You declare class as private. So it will be invisible outside. Then there is conflict if it be not visible then how people will know to assign and get that object without knowing its type. So that type should be public and visible
dim m as new MainClass()
m.ExampleProperty=? ' What is ExampleProperty ?int , object. So it should not be unknown
Another way you claim that you are not going to use that property outside.This way it is ok to have private class inside.
'Explicitly make property to be used only within class
Private Property ExampleProperty As ExamplePropertyClass
You do this with interfaces:
Public Interface IDoesSomething
Sub DoSomething()
End Interface
Public Class MainClass
Public Sub New()
m_example = New InternalClass
End Sub
Private m_example As IDoesSomething
Public ReadOnly Property Example() As IDoesSomething
Get
Return m_example
End Get
End Property
Private Class InternalClass
Implements IDoesSomething
Public Sub DoSomething() Implements IDoesSomething.DoSomething
End Sub
End Class
End Class

VB.Net Create Database table from class property

I'm trying to create an inheritable class(OF t) in vb.net that I will pass it a class of objects. Inside the class of objects I want to use the class properties to create a corresponding database table. Like below
Public Class SampleClass
#Region "Properties"
Private newPropertyValue As String
Public Property NewProperty() As String
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
#End Region
Public Sub New()
End Sub
End Class
I'm new to vb.net so I don't know my way around exactly.
I was looking into class attributes for this action but they do not fully make sense to me yet. Thanks in advance.
You will want to get well versed on something called Code First. This should get you started.

Is there a way to make a value accessible only to the parent of a nested class VB.NET?

In general, according to the OOP paradigm, my understanding of encapsulation basically says:
If a member is private, it can only be accessed by the class.
If a member is protected, it can only be accessed by the base class and any derived classes.
If a member is public, it can be accessed by anyone.
If I have a nested class, can I declare a property to be accessible only to that class and the parent class it's nested within? For example:
Public Class ContainerClass
Public Class NestedClass
Protected myInt As Integer ' <- this is what I am wondering about '
Protected myDbl As Double ' <- this is what I am wondering about '
Sub New()
myInt = 1
myDbl = 1.0
End Sub
End Class
Private myNestedObject As New NestedClass
' this function is illegal '
Public Sub GrowNestedObject(ByVal multiplier As Integer)
myNestedObject.myInt *= multiplier
myNestedObject.myDbl *= multiplier
End Sub
End Class
In the example, I cannot directly access myNestedObject.myInt or myNestedObject.myDbl from an instance of ContainerClass if those members are Private or Protected. But suppose I don't want to make them Public, because then they are TOO exposed: they can be altered from anywhere, not just within a ContainerClass object. Declaring them Friend would still be too weak as that would allow them to be altered from anywhere within the application.
Is there any way to accomplish what I am going for here? If not, can anyone think of a more sensible way to achieve something like this?
There is no way of doing this directly with a combination of accessibility modifiers.
The best way I can think of doing this is as follows. It involves an extra level of indirection.
Create a Nested Interface with Private accessibility. This will give only the Parent class and nested children access
Add the fields you want access to to that interface
Make the Nested class implement the interface
Make all of the implementations have private accessibility
Now the parent class and only the parent class will have access to those properties and methods.
For Example:
Class Parent
Private Interface Interface1
ReadOnly Property Field1() As Integer
End Interface
Public Class Nested1
Implements Interface1
Private ReadOnly Property Field1() As Integer Implements Interface1.Field1
Get
Return 42
End Get
End Property
End Class
Sub New()
Dim child As Interface1 = New Nested1
Dim x = child.Field1
End Sub
End Class
Based on JaredPar's answer, you could use a Private ChildClass but a Public Interface that reveals only what it sould show :
Public Class ParentClass
Public Interface IChildClass
ReadOnly Property i() As Integer
Sub SomeSub()
End Interface
Private Class ChildClass
Implements IChildClass
Public myInt As Integer
Public ReadOnly Property i() As Integer Implements IChildClass.i
Get
Return myInt
End Get
End Property
Public Sub SomeSub() Implements IChildClass.SomeSub
End Sub
End Class
Public Shared Function GetNewChild() As IChildClass
Dim myChild = New ChildClass()
myChild.myInt = 3
Return myChild
End Function
End Class
Usage :
Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()