Multiple Type Cast With or Without Generics

Status
Not open for further replies.

Element6

Well-known member
Joined
Feb 16, 2010
Messages
85
Programming Experience
5-10
Ok, this looks junky to me and I tried a lot of approaches; Generics won't allow me to cast the types on the fly and use MemberwiseClone() because it is 'Protected'.

Does anyone know a "short form" of doing this? I tried CType by Object.GetType on the fly; but the IDE cannot resolve the MemberwiseClone().

VB.NET:
Private lastObj as Object = Nothing

Public Function IsObjectedDifferent(CurrentObject as Object) as Boolean
            If CurrentObject Is Nothing Then Return False
            If LastObject Is Nothing Then Return False

            Dim returnValue as Boolean = CurrentObject.Equals(lastObj)

            If TypeOf (CurrentObj) Is SomeClassA Then
                lastObj  = CType(CurrentObj, SomeClassA).MemberwiseClone
            ElseIf TypeOf (CurrentObj) Is SomeClassB Then
                lastObj = CType(CurrentObj, SomeClassB).MemberwiseClone
            ElseIf TypeOf (CurrentObj) Is SomeClassC Then
                lastObj = CType(CurrentObj, SomeClassC).MemberwiseClone
.
.
.
            ElseIf TypeOf (CurrentObj) Is SomeClassZ Then
               lastObj = CType(CurrentObj, SomeClassZ).MemberwiseClone
            End If

            Return returnValue
End Function

I am trying to make a generalized function to handle if the Object is Changed; or If the values are different.

This seems like way too much code for such a simple task to me, and I have a lot of classes to compare; is there away to get the class defination dynamically so that the CType function will handle it?

Generics wont allow for Complex Late Binding.
 
Last edited:
How can you cast as a type if you don't know what the type is? A cast is a specific instruction to the compiler to treat a reference or value as a specific type. If you don't know what that type is at compile time then a cast is impossible.

If you want to make your code completely generalised then you'll have to use reflection. You can first test whether two objects are the same type and, if they are, loop through the properties of that type and compare the values of those properties for each object.
 
That is what I am doing. At least trying to.

I wanted to do something like this, it's a hack I know but I think it can be done; just not sure how to approach this; I want to inherit the code so I am trying to keep a generalized approach.

VB.NET:
Dim WorkingObject As Object = Nothing
Dim TypeConversion As Type = SomeArbitraryClass.GetType.UnderlyingSystemType
WorkingObject = CType(WorkingObject, TypeConversion)

But it won't allow me to pass the TypeConversion Type; Is there a way of doing this; since I have the type info in the "UnderlyingSystemType"?

(If that worked; I was going to do the compare in a loop against the workingobject with TypeOf dynamically)

I know that either GetType or Type does a string compare against the name; but I was trying to do this by referencing the object type incase I change the names at a later date to minimize the code rework. Maybe I have to enummerate the types and do it that way but not sure how to.
 
What you're trying to do is not possible. A data type and a Type object are very much not the same thing. As I have already said, you cannot cast to a type that is not known to you at compile time. As I have also already said, you would have to use reflection.

The Type class is basically where it all starts with reflection. You call GetType on an object to get a Type object that represents its data type. You can then get PropertyInfo objects that represent the properties of that type. You can then use those PropertyInfo objects to get the values of the corresponding properties of any instance of that type. That said, you'd compare the types first because if the types don't match then obviously the objects don't match.
 
I found away to do it; The cast information is carried state so it is possible; it's just a matter of accessing so I came up with a little dynamic hack. Which works; it's big - but it's reusable and generalized.

VB.NET:
.
.
.
                                Dim SimpleCompare As Boolean = True

                                Dim StringRef As String = ""
                                Dim DecimalRef As Decimal = 0.0
                                Dim BooleanRef As Boolean = False
                                Dim LongRef As Long = 0
                                Dim IntegerRef As Integer = 0
                                Dim Int32Ref As Int32 = 0
                                Dim Int64Ref As Int64 = 0
                                Dim CharRef As Char = ""
                                Dim ByteRef As Byte = 0
                                Dim DateRef As Date = "1/1/1983"
                                Dim DoubleRef As Double = 0.0
                                Dim ShortRef As Short = 0
                                Dim SingleRef As Single = 0

 Select Case CompareProperties(x).PropertyType.ToString
                                        Case ByteRef.GetType.ToString
                                        Case DateRef.GetType.ToString
                                        Case StringRef.GetType.ToString
                                        Case CharRef.GetType.ToString
                                        Case BooleanRef.GetType.ToString
                                        Case IntegerRef.GetType.ToString
                                        Case Int32Ref.GetType.ToString
                                        Case Int64Ref.GetType.ToString
                                        Case LongRef.GetType.ToString
                                        Case DoubleRef.GetType.ToString
                                        Case DecimalRef.GetType.ToString
                                        Case ShortRef.GetType.ToString
                                        Case SingleRef.GetType.ToString
                                        Case Else
                                            ' Arrays, Object, and User Defined Classes comparing
                                            SimpleCompare = False
                                    End Select
.
.
.

so you can Cast on the fly with indirect referencing. I knew it could be done - I just think the solution is too big; still looking for a way to do it with a single variable.

Maybe for CType I can try setting the multicasttypes to a variable and just pass it that way.

BTW it doesn't have to be PropertyInfo either; I can use flat GetType.ToString (which is reflection I know) but still it's carried state and as long as the system.types are consistant I don't care.
 
If I had to, I would compare arbitrary objects something like this:
VB.NET:
Public Function AreEqual(ByVal obj1 As Object, ByVal obj2 As Object) As Boolean
    'Assume equal until proven otherwise.
    Dim result As Boolean = True

    Dim typ As Type = obj1.GetType()

    If obj2.GetType() Is typ Then
        For Each prop As PropertyInfo In typ.GetProperties()
            If Not prop.GetValue(obj1, Nothing).Equals(prop.GetValue(obj2, Nothing)) Then
                'If at least one property isn't the same then the objects can't be equal.
                result = False
                Exit For
            End If
        Next
    Else
        'If the types aren't the same then the objects can't be equal.
        result = False
    End If

    Return result
End Function
That might stand a bit of improvement. It's untested for one thing. Also, all objects with indexed properties will return False, so you might want to make allowances for that too.
 
That was my first approach; very similar at least.

The issue becomes more complicated because I use indexed properties with multiple signatures; so it becomes important to know the Object Type information; and mixed type information.

In this case Lets suppose I have 4 different classes with variable indexes mixed with variable class types. I rarely use collections or lists and typically handle arrays as a norm but not always.

So, in order to pass the correct Indexed signature you need to know the property index types; and that gets complicated. You need to start looking at the property type; and in addition the way I handle property accessing I can cause an infinate loop if I don't restrict my equalities to a range. *Internal Exceptions*

So knowing the state and type of the object becomes very important in my Overriding "Equals" Function.
 
This is my solution for a Generalized Approach to the problem (NOT FREEWARE) so the rights are reserved but it gives you a basic understanding on why I am complaining that Microsoft is LAZY because the information can be derived, so if Microsoft tries to pick up this code in any form I want a million USD because your too greedy and now I am going to be. Non-Negotiable.

Otherwise everyone else must give coding credit to where its due :

The Developers of :
E v o l u t i o n A r t s, L L C
a limited liability corporation

Matthew F. Egan (Systems Programmer and Engineer)

Generalized TypeOf for VB.NET Approach Function DerivedType.

Reserved code removed

Usage :

Reserved code removed

So there you have it; the DynamicCType Runtime conversion; with DerivedType Information.

Combined Usage :

Reserved code removed

Redundancy aside; in my actual code I do some checking.

AGAIN NOT FREEWARE and ALL RIGHTS ARE RESERVED.
 
Last edited:
Status
Not open for further replies.
Back
Top