Accessing private functions and variables in a public class from another class - vb.net

As the title says, I've run into a problem where I have to call certain private functions in a class.
Public Class Class1
private Type
Private Name
private Function()
I have tried doing the following:
Public Class Class1
Dim copyClass As Class1
Public Shared Instance As Class1
Public Sub New()
MyBase.New()
copyClass = Me
End Function
Public Function createInstance() As Class1
Instance = copyClass
Return Instance
End Function
Then in my other class, Class2, I have added:
Public Property callingObject As wdCopyPatch
Get
Return copyObject
End Get
Set(value As wdCopyPatch)
copyObject = value
End Set
End Property
now, I can just do the following from within a function in Class1
Dim Ob as Class2
Ob.callingObject = createInstance()
This allows me to use copyObject from Class2 but only gives me access to Class1's Public Functions and variables. What can I do to be able to access Class1's Private functions and variables without making everything public?
Any advice or comments are appreciated :)

As per my comments, here's some code:
Sandbox is my class with a private function, and a public property getting info from that private function.
otherclass, calls this property of sandbox.
Public Class sandbox
Public ReadOnly Property myHiddenValue() As String
Get
Return get_that_sucker()
End Get
End Property
Private Function get_that_sucker()
Return "boo!"
End Function
End Class
Public Class otherClass
Public Sub mySub()
Dim mysandbox As New sandbox
MsgBox(mysandbox.myHiddenValue)
End Sub
End Class

Related

Inner class Factory Method

I have tried to implement the Factory method with a trick, but for some reason is not working:
Public Class MetamodelElement
Public Class MetamodelElementFactoryBase
End Class
Private Sub New()
End Sub
End Class
Public Class MetamodelElementFactory : Inherits MetamodelElement.MetamodelElementFactoryBase
Function CreateMetamodelElement() As MetamodelElement
Return New MetamodelElement()
End Function
End Class
It says that the class does not have access to the private method (constructor).
I have followed an example from C# in this post:
Hidden Features of C#?
The compiler complains that you are trying to use the Private constructor from outside of the class. That is not allowed. So either make it Public or don't call it.
Public Class MetamodelElement
Public Class MetamodelElementFactoryBase
End Class
Public Sub New() ' <---- HERE!!! Now it works because it's public
End Sub
End Class
Public Class MetamodelElementFactory
Inherits MetamodelElement.MetamodelElementFactoryBase
Function CreateMetamodelElement() As MetamodelElement
Return New MetamodelElement() ' <--- HERE was the error
End Function
End Class
You can access private class members only from inside of the class.
MSDN: Access Levels
According to the C# code that you've linked you have to move the constructor into the class that you are inheriting from. Then you can also use Protected:
Public Class MetamodelElement
Public Class MetamodelElementFactoryBase
Protected Sub New()
End Sub
End Class
End Class

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

VB.NET - reference to an object under construction is not valid when calling another constructor

Is there any difference between doing this:
Public Class Class1
Protected Test1 As String
Public Sub New(ByVal test2 As String)
Test1 = test2
End Sub
End Class
Public Class Class2
Inherits Class1
Public Sub New()
MyBase.New("called from class 2")
End Sub
End Class
and this:
Public Class Class1
Protected Test1 As String
End Class
Public Class Class2
Inherits Class1
Public Sub New()
Test1 = "Called from class 2"
End Sub
End Class
In the first example, the superclass instance variable is initialised in the constructor. In the second example, the superclass instance variable is initialised in the subclass.
The reason I ask is because I am trying to do this from the subclass:
Public Sub New()
MyBase.New( System.Configuration.ConfigurationManager.AppSettings.Item("PurgeFile" & Me.GetType.Name), & _
System.Configuration.ConfigurationManager.AppSettings.Item("PurgeHeader" & Me.GetType.Name) )
End Sub
and I am getting an error: "reference to an object under construction is not valid when calling another constructor".
You can't use Me within MyBase.New() call, so following part of your code is invalid:
Me.GetType.Name
Update
There is huge difference your 2 samples: First one doesn't allow Class1 initialization without constructor parameter and the second one does.
I would rather think about something like:
Public MustInherit Class Class1
Public MustOverride ReadOnly Property Test1 As String
End Class
Public Class Class2
Inherits Class1
Private _Test1 As String = "Called from class 2"
Public Overrides ReadOnly Property Test1 As String
Get
Return _Test1
End Get
End Property
End Class
Reference from MSDN

VB generics with constraints -- type casting and inheritance?

Take this scenario:
Public Interface IMyClass
End Interface
Public mustinherit class MyBaseClass : implements IMyClass
End Class
public class MyClass : inherits MyBaseClass
End Class
public class MyModel(of t as IMyClass)
private Dim _parameter as t
Public Sub New(byval parameter As t)
_parameter As t
End Sub
End class
In my controller, I can do this with no problem:
Dim _myclass as IMyClass = new MyClass()
Can I do something similar with this:
Dim _myModel as MyModel(of IMyClass) = new MyModel(of MyClass)
???
My initial thought was wrong, as I thought the conversion could be done automatically, but it appears it is not done. Any way to achieve the same thing within .NET?
EDIT
I updated the MyModel class to show more of what I was doing. I want to constrain the instance I create, but then do what would be a narrowing conversion with traditional, non-generics code. Basically, my partial Razor views would require the explicit model, and those views end up rendering another view that will take that model and display it. Because the models all implement or inherit a class that implements IMyClass, all the methods should exist on all of the instances and should be callable but the types are not interchangable.
Let’s modify MyModel slightly, shall we?
Public Class MyModel(Of T As IMyClass)
Private _parameter As T
Public Sub Something(parameter As T)
_parameter = parameter
End Sub
End class
Public Class MyClassA : Inherits MyBaseClass
End Class
Public Class MyClassB : Inherits MyBaseClass
End Class
Dim _myModel As MyModel(Of IMyClass) = New MyModel(Of MyClassA)()
_myModel.Something(New MyClassB()) ' Boom!
If the assignment were allowed the last line would pose a problem: MyMode(Of MyClassA)._parameter has type MyClassA but the last line would assign an object of the (unrelated) type MyClassB. This is illegal and so VB forbids it.
Do you need multiple varieties of MyModel, or are you just attempting to require that the stored object be constrained to IMyClass?
Simplest approach (that might not do everything you need):
Public Interface IMyClass
Sub DoIt()
End Interface
Public Class MyModel
Private ReadOnly _parameter As IMyClass
Public Sub New(parameter As IMyClass)
_parameter = parameter
End Sub
Public Sub DoItToIt()
_parameter.DoIt()
End Sub
End Class
Public Class MyClassA
Implements IMyClass
Public Sub DoIt() Implements IMyClass.DoIt
End Sub
End Class
Public Class Tests
Public Sub Main()
Dim model1 As MyModel = New MyModel(New MyClassA)
model1.DoItToIt()
End Sub
End Class
Next step up in complexity is to define an interface IHasMyClass for classes that contain an IMyClass. This supports manipulations based on the allowed type, and the actual type, of the contained object:
Public Interface IMyClass
Sub DoIt()
End Interface
Public Interface IHasMyClass
Function GetIt() As IMyClass
Function GetItsType() As Type
Function GetAllowedType() As Type
End Interface
Public Class MyModel(Of T As IMyClass)
Implements IHasMyClass
Private ReadOnly _parameter As IMyClass
Public Sub New(parameter As IMyClass)
_parameter = parameter
End Sub
Public Sub DoItToIt()
_parameter.DoIt()
End Sub
Public Function GetItAsT() As T
Return _parameter
End Function
Public Function GetIt() As IMyClass Implements IHasMyClass.GetIt
Return _parameter
End Function
Public Function GetItsType() As Type Implements IHasMyClass.GetItsType
Return _parameter.GetType()
End Function
Public Function GetAllowedType() As Type Implements IHasMyClass.GetAllowedType
Return GetType(T)
End Function
End Class
Public Class MyClassA
Implements IMyClass
Public Sub DoIt() Implements IMyClass.DoIt
End Sub
End Class
Public Class Tests
Public Sub Main()
' Allow any IMyClass
Dim model1 As MyModel(Of IMyClass) = New MyModel(Of IMyClass)(New MyClassA)
model1.DoItToIt()
Dim it As IMyClass = model1.GetIt()
Dim allowedT As Type = model1.GetAllowedType()
' Restrict to MyClassA
Dim modelA As MyModel(Of MyClassA) = New MyModel(Of MyClassA)(New MyClassA)
modelA.DoItToIt()
Dim itA1 As IMyClass = modelA.GetIt()
Dim itA2 As MyClassA = modelA.GetItAsT()
Dim allowedTA As Type = modelA.GetAllowedType()
End Sub
End Class
In Tests(), notice that we now need to declare whether we are creating a MyModel that accepts ANY IMyClass MyModel(Of IMyClass), or one that requires a specific sub-class MyModel(Of MyClassA).
If we want to manipulate MyModels, that may be either of the above types, we use the common interface:
Dim model As IHasMyClass
model = model1
...
model = modelA
Or in your case, to support all the functionality of MyModel, rename IHasMyClass as IMyModel, and add the various MyModel functions, but instead of T, use IMyClass:
Public Interface IMyModel
Function GetIt() As IMyClass
Function GetItsType() As Type
Function GetAllowedType() As Type
Sub DoItToIt()
Function CompareIt(other As IMyClass) As Integer
End Interface
And make appropriate changes/additions to IMyClass and MyModel.
Then it becomes possible to do:
Dim model As IMyModel = modelA
If model.CompareIt(model1.GetIt()) > 0 ...

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