VB6 Member variable inheritance - variables

I'm having trouble inheriting a (public) variable, let's say
Public Var As ClassThatIsIndependent
The declaration above generates no trouble for itself, however, if i inherit the class that holds it
Implements BaseClass
I get the error "object module needs to implement variable for interface". I've tried these options (both inside ChildClass)
Public Var As ClassThatIsIndependent
and
Public BaseClass_Var As ClassThatIsIndependent
But none of them solves the problem. Any alternative? I'm open to possible Set/Get solutions, however, i'd prefer to maintain Var as a public variable.

Per the Visual Basic 6.0 Programmer's Guide, Polymorphism, Implementing Properties section:
Suppose we give the Animal class an Age property, by adding a Public variable to the Declarations section:
Option Explicit
Public Age As Double
The Procedure drop downs in the code modules for the Tyrannosaur and Flea classes now contain property procedures for implementing the Age property,
…
Using a public variable to implement a property is strictly a convenience for the programmer. Behind the scenes, Visual Basic implements the property as a pair of property procedures.
You must implement both procedures. The property procedures are easily implemented by storing the value in a private data member, as shown here:
Private mdblAge As Double
Private Property Get Animal_Age() As Double
Animal_Age = mdblAge
End Property
Private Property Let Animal_Age(ByVal RHS As Double)
mdblAge = RHS
End Property
The private data member is an implementation detail, so you have to add it yourself.
That is, the "public interface" is exactly the same whether you use a Public variable or define them with Property Get/Let. And to implement a property in an interface, you can't use the Public variable approach and need to use the Property Get/Let syntax and handle the data storage for it in your own private variables.

Related

How to extend derived classes by defining class(es) that exposes the instance as a property

I have a class that I would like to extend by defining a new class that contains the first class as a public property, as well as additional added properties. However, the class that I'm extending has multiple derived types, which should be treated the same in the extension class.
Below is an example of what I am trying to do:
Public Class ClassA
End Class
Public Class ClassB
Inherits ClassA
End Class
Public Class ClassC
Inherits ClassA
End Class
Public Class BaseExtended
Public Property Foo As ClassA
Public Property ExtendedMetaData1 As Double
Public Property ExtendedMetaData12 As Integer
End Class
Public Class DerivedExtendedB
Inherits BaseExtended
Public Property Foo As ClassB
End Class
Public Class DerivedExtendedC
Inherits BaseExtended
Public Property Foo As ClassC
End Class
The code that uses an instance of any of the 'extended' classes would then need use that instance appropriately depending on it's type. There would be many cases where the property 'Foo' needs to be accessed and modified outside of the class that it belongs to.
If I were to implement something like what I have shown above, that would require that I first cast it to the required type before accessing or modifying it. Ideally I would like to do that inside the 'DerivedExtended' class; The alternative, I think, would be to duplicate code to cast that property would [hundreds of times] in the client code.
Private Sub ClientUsesObject(bar As BaseExtended)
' Perform a task that is agnostic Foo type
' Would not require that Foo be cast to any specific type
If bar.GetType() Is GetType(DerivedExtendedB) Then
Dim barCast As DerivedExtendedB = DirectCast(bar, DerivedExtendedB)
' Perform task that requires Foo to be of type ClassB
ElseIf bar.GetType() Is GetType(DerivedExtendedC) Then
Dim barCast As DerivedExtendedC = DirectCast(bar, DerivedExtendedC)
' Perform task that requires Foo to be of type ClassC
End If
End Sub
What I'm looking for is advice outlining or describing a design pattern that can handle this situation. I've searched for quite a while, and have not been able to find any examples that solve this problem.
I realize that this may be somewhat of an "XY" problem. I'm working with existing code that simply assumes all instances are of the same derived type (when in fact some instances are of the other derived type). As such, the existing code does not work. To me what I've tried to outline above seems like the most straightforward path, but I'm open to alternative if this is just the wrong approach.
This pattern of type covariance in derived classes is the canonical reason for what is called in C++ the "Curiously Recurring Template Pattern" and has been called in .NET the "Curiously Recurring Generic Pattern." I believe it's also sometimes referred to as "F-Bounded Polymorphism" (not a computer scientist, so I might have the reference wrong).
You can write a base class like this:
Public Class Base(Of TDerived As Base)
Public Overridable Property foo As TDerived
End Class
And then use it like this:
Public Class MyDerived
Inherits Base(Of MyDerived)
End Class
Then, the derived class has a property foo whose type is MyDerived. No casting required by clients.
However, this has some limitations. It works best when you don't need to switch back and forth between derived and base. There is no one Base, so you can't declare instances of it. If you want to be able to declare something as Base, then you end up needing to fall back on a non-generic base class. This will still work well for certain usage patterns where you don't need to convert from base to derived, but otherwise you run right back into the casting problems you are trying to avoid.
Eric Lippert has written a bit about this pattern. He's always interesting to read, so I'd recommend looking up his commentary.
Another alternative to consider, if the generic approach doesn't work for you, is code generation. You can use T4 templates to process a compact description of what your code should be, and generate the code files from them. A long list of casts is less tedious if you only write the machinery to generate it, you don't write them all out explicitly.

Visual Basic: Read only Visability of Structure members

Ok, so this kind of follows after a previous question that I've asked involving structures and classes. So referencing this question (and I am using classes now for the base) I have one member of the class that is an array (and I know that I have to declare it without dimensions) that as part of the constructor I want it to define the dimensions of the array. When I was initially trying to do the ReDim the compiler was unhappy because I was declaring the member as ReadOnly. While what I'm doing with the array has it's own question of feasibility to it that's not what I'm asking about as it raised a different issue that I must answer first.
Is there a way to make members of a class/structure read only outside of the class/structure but modifiable with in the class/structure without having to use properties or internal functions/subs to gain the read access?
Basically like declaring the member private but you can at least read the member outside the class/structure. Just not anything else.
You can do something like this
Private _some As String
Public Property Some As String
Get
Return _some
End Get
Private Set(value As String)
_some = value
End Set
End Property
No. On its own, there is no way to make a class field public for reading, but private for writing. Accessibility modifiers on a field affect both read and write.
The cleanest way to do what you want is to define a private field in your class, and define a public property getter:
Private _dummy As String
Public Property Dummy() As String
Get
Return _dummy
End Get
End Property
Granted, it would be nice to be able to express this more succinctly, as is possible with C# using auto-implemented properties:
public string Dummy {get; private set;}

VB.NET - I'm Refactoring and Could Use Some Help

I'm working with vb.net, wcf, wpf and I'm refactoring working code with the hope of being able to reduce some amount of redundancy. I have a bunch of methods that get called in several places throughout the code that only have a slight variation from each other and I would like to replace them with a single method instead.
Specifically, each of the redundant methods process an 1-d array that contain different objects I have created. There are several of these different object types each with different signatures but they have all have a "name" and "Id" property. (Also these objects don't have a shared base class but I could add that if needed.) Each of the redundant methods deal with a different one of the object types.
To refactor the code I would like to pass any of the different object arrays to a single new method that could access the "name" and "id" properties. I'm trying to write this new method in a fashion that wouldn't require me to update it if I created more objects down the road.
I've done some reading on Delegates and Generic Classes but I can't really figure out how this fits in. It would almost be as if I wanted to create a generic class that could handle each of my object types but then somehow also access the "name" and "id" propeties of the different object types.
Any help you can provide would be appretiated. Also, please keep in mind this project is written in VB.net.
Thanks
Mike
It sounds like having your object implement a common interface or have a shared base class would be best. Interfaces give you the most flexibility down the road if you ever need to pass a class to this method that must derive from some other class that does not implement the interface. However, a base class that implements the interface may also be useful just to reduce the duplicate declarations of these properties.
Public Interface IThingThatHasNameAndId 'good name not included
ReadOnly Property Name As String
ReadOnly Property Id As Integer
End Interface
Once you have the interface, you can then pass arrays of types implementing the interface as IEnumerable(Of IThingThatHasNameAndId) or make a generic method taking T() and constrain T to the interface.
Make a base class with the Name and ID properties, then you can make a method that takes in any class that derrives from that class.
Public Function TestFunction(Of t As YourBaseClass)(Byval obj As t) As Boolean
If obj.Name = "Some Name" AndAlso obj.ID = 1 Then
Return True
Else
Return False
End If
End Function

How do I treat two similar types as one?

In VB.NET, I am trying to talk to a webservice (that can't be changed) to create and update customer data.
The CreateCustomer service expects an object of type ConsumerPerson and the ChangeCustomer service expects an object of type ChangeData.
The properties of these two object are exactly the same, so I thought it would be wise to just set the properties using one single function.
However, I am unable to find a way to tell my function that I want to fill either the ConsumerPerson or the ChangeCustomer object.
How do I make this work without late binding problems?
An interface sounds like your best approach. Here is a short code snippet. I picked a simple property named "Name" of type string. It should be easy to modify with the actual properties on your class.
Public Interface ICustomerData
ReadOnly Property Name As String
End Interface
Public Class ConsumerPerson
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
Public Class ChangeData
Implements ICustomerData
Public ReadOnly Property Name As String Implements ICustomerData.Name
Get
return _name
End Get
End Property
End Class
use an interface !
declare an interface IFoo, and implement its members in your subclasses ConsumerPerson and ChangeCustomer. That's exactly what interfaces are for.
You create an interface which both classes implements.
Is it not possible to overload your function with the second data type?
If you cannot change your objects, but they share the same field names, you could xml serialize the data and deserialize as the other class. - You should strongly consider the performance implications of this; however, it would give you the functionality you're asking for.

Access private member variable of the class using its object (instance)

Here is a VB.NET code snippet
Public Class OOPDemo
Private _strtString as String
Public Function Func(obj as OOPDemo) as boolean
obj._strString = "I can set value to private member using a object"
End Function
End Class
I thought we cannot access the private members using the object, but perhaps CLR allows us to do that. So that means that access modifiers are based on the type and not on the instance of that type. I have also heard that c++ also allows that..
Any guesses what could be the reason for this?
Edit:
I think this line from the msdn link given by RoBorg explains this behaviour
"Code in the type that declares a private element, including code within contained types, can access the element "
Your question is quite confusing but I think I've understood it as:
"Why can I access another instance (of my class)'s private variables?"
And you're right - in all OOP languages I've used you can access private variables from other instances, precisely because access permissions are based on where the code is, rather than to which object instance it 'belongs'.
It might be hard to implement copy constructors or equality operators otherwise.
Here's the section about access levels in MSDN.