How do I treat two similar types as one? - vb.net

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.

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;}

Use one attribute with state or two attributes without state

I'm starting to learn about custom attributes and I have one question for the more experienced users:
I want to mark my properties as "TypeA" or "TypeB" with attributes, so I can check them with reflection. Is it better to have only one attribute with state, like this:
Public Class FlavourAttribute
Inherits Attribute
Private _flavour As Flavours
Public ReadOnly Property Flavour() As Flavours
Get
Return _flavour
End Get
End Property
Public Enum Flavours
Sweet = 0
Acid = 1
End Enum
Public Sub New(ByVal flavour As Flavours)
_flavour = flavour
End Sub
End Class
Or is it better to use two attributes without state:
Public Class SweetAttribute
Inherits Attribute
End Class
Public Class AcidAttribute
Inherits Attribute
End Class
I'm asking about drawbacks of these two approaches, or possible alternatives.
Thanks!
There's not an answer to your general question, but the answer to your specific question would be to use the latter. Whether or not something is sweet is independent of whether or not it's acidic, so you're talking about different things. If, on the other hand, you were dealing with related (or mutually exclusive) properties, they should be on one attribute.
After a while of playing with custom attributes I would say I've discovered a good reason to prefer separate attributes over one single attribute with state: it is far more simple and readable to check if one property has a single attribute than checking a property of the attribute.
Following with the example in the question, with separate attributes, we would have:
For Each prop As PropertyInfo In MyTipe.GetProperties
thePropertyIsSweet= Attribute.IsDefined(prop , GetType(SweetAttribute))
thePropertyIsAcid= Attribute.IsDefined(prop , GetType(AcidAttribute))
Next
While with a single attribute with state I should first check if the property has it, then cast an attribute object from it and retrieve its two properties.
I'm a wrong with this reasoning?

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

Can I qualify the type of a parameter in VB.NET?

This is kind of two questions (one more specific than the other).
If I have a method like this:
Public Function Blah(String Foo)
End Function
Can I qualify Foo against another type (for instance can I require that Foo be a String that also implements IInterface?).
I'm imagining something vaguely similar to this:
Public Function Blah(RandomObject Foo Where RandomObject Is IInterface)
End Function
Additionally, is there any way to qualify the Type parameter?
For instance, can I require that the Type I take as a parameter is of a particular class tree?
Public Function Blah(Type t Where Type Of String)
End Function
I should mention that I am using this in the context of a property of an attribute so the class declaration itself cannot be generic (this is purely focused on qualifying a method parameter rather than typing a class and its methods).
This looks like a case for generics to me. Your method signature would be something like this in VB.NET:
Public Function Blah(Of T As {IImplementedByT})(Foo As T)
This specifies that Foo can be of any type T as long as T implements IImplementedByT. Note that this method can be generic without the containing class needing to be generic. If you want T to be a class derived from RandomClass that also implements this interface, you can specify both constraints:
Public Function Blah(Of T As {RandomClass, IImplementedByT})(Foo As T)
You can do the first for a generic type, but not for a nongeneric type. Basically a variable (including a parameter) can only have one compile-time type, so you can't say "it has to be a Foo and an IBar - you have to pick one or the other. Generics let you say "it has to be some type T where T derives from Foo and implements IBar" though.
Generics is a huge topic - too big to cover in a Stack Overflow answer - but Microsoft has a good introductory article.
As for your second question - no, you can't do that. The Type value will only be known at execution time, so it has to be an execution time check. You can write that check fairly easily though, with Type.IsAssignableFrom.
Not sure what you mean by "Foo be a String that also implements IInterface".
string class is sealed, so you can't inherit from it & hence you cant implement an interface on top of it.
I hope I am on the right page.