Current Cast vs. Object Type

D

Dinsdale

I am trying to determine what the current cast of an object is.
Essentially, if I use GetType, it always returns the original type of
the object created but I want to know what the current cast of the
object is (i.e.: is it still cast as a Derived class, or is it cast as
a Base class?) Here is some pseudo code to show the example.

Class Base

....
End Class

Class Derived : Inherits Base

....
End Class

Public Sub Main()
Dim derived1 as New Derived()
Dim base1 as Base

base1 = Ctype(derived1, Base)

Console.Writeline (base1.GetType().ToString())

End Sub

'Output would be "Derived". How to I determine what the CAST is? i.e.
Base?

Thanks in advance.

Dinsdale
 
A

Armin Zingler

Dinsdale said:
I am trying to determine what the current cast of an object is.
Essentially, if I use GetType, it always returns the original type
of the object created but I want to know what the current cast of
the object is (i.e.: is it still cast as a Derived class, or is it
cast as a Base class?) Here is some pseudo code to show the example.

Class Base

...
End Class

Class Derived : Inherits Base

...
End Class

Public Sub Main()
Dim derived1 as New Derived()
Dim base1 as Base

base1 = Ctype(derived1, Base)

Console.Writeline (base1.GetType().ToString())

End Sub

'Output would be "Derived". How to I determine what the CAST is?
i.e. Base?

Thanks in advance.

Dinsdale


Why would you want to know this? The compiler permits what's possible with
the reference anyway. I don't dare to say "look at the dim statement" ;-)

With local variables this is not possible. With fields, you could use
reflection (whyever) and have a look at System.Type.DeclaringType.


Armin
 
P

Patrice

What are you trying to do ? You could get the base type or an ancestor type
using Reflection.

Strictly speaking you can't do that as once you casted the variable to
another variable you don't have any information about where it came from.
Basically this is bit as if you wanted to know if an integer variable was
created from a constant in the code or parsed from a string or taken from
another variable etc....

IMO the first step would be to explain what you are trying to do so that we
can understand if reflection would be enough or if someone can suggest
another way of doing whatever you are trying to do.
 
D

Dinsdale

Why would you want to know this? The compiler permits what's possible with
the reference anyway. I don't dare to say "look at the dim statement" ;-)

With local variables this is not possible. With fields, you could use
reflection (whyever) and have a look at System.Type.DeclaringType.

Armin

Ya, I was waiting for someone to say that. lol.

The database uses a sequence number for all primary keys in the table
and we are trying to create a class library around it. I didn't want
to have to code derived classes as having base_id, derived_id,
derived_2_id so I've created a collection of identifiers (including
concurrency identifiers such as modified date). Then the lowest base
class has an ID property that looks at the type and returns the
correct Identifier value from the collection for that cast. The
problem is GetType() doesn't do this, as noted above. The following is
the code that doesn't work. :(

Public Property ID() As Integer
Get
CheckIdentifiers() 'Ensures that there are in fact identifiers
Dim typeName As String
typeName = Me.GetType.Name
Return Identifiers(typeName).ID
End Get
Set(ByVal value As Integer)
CheckIdentifiers()
Dim typeName As String
typeName = Me.GetType.Name
Identifiers(typeName).ID = value
End Set
End Property


So, If I create an object of DerivedType2 and want to cast it as a
BaseType and then get the BaseType.ID property, the above code
executes as DerivedType2 so I get the wrong ID.

Unfortunately, in my test app the DeclaringType is coming up as
Nothing, but thanks for the help. It gives me something to work on...

Cheers
Dinsdale
 
D

Dinsdale

What are you trying to do ? You could get the base type or an ancestor type
using Reflection.

Strictly speaking you can't do that as once you casted the variable to
another variable you don't have any information about where it came from.
Basically this is bit as if you wanted to know if an integer variable was
created from a constant in the code or parsed from a string or taken from
another variable etc....

IMO the first step would be to explain what you are trying to do so that we
can understand if reflection would be enough or if someone can suggest
another way of doing whatever you are trying to do.

I'm not concerned with the historic value, I'm concerned about the
current casting. "What is the name of the object reference type that I
am currently using?"
 
A

Armin Zingler

Dinsdale said:
Ya, I was waiting for someone to say that. lol.

The database uses a sequence number for all primary keys in the
table and we are trying to create a class library around it. I
didn't want to have to code derived classes as having base_id,
derived_id,
derived_2_id so I've created a collection of identifiers (including
concurrency identifiers such as modified date). Then the lowest base
class has an ID property that looks at the type and returns the
correct Identifier value from the collection for that cast. The
problem is GetType() doesn't do this, as noted above. The following
is the code that doesn't work. :(

Public Property ID() As Integer
Get
CheckIdentifiers() 'Ensures that there are in fact identifiers
Dim typeName As String
typeName = Me.GetType.Name
Return Identifiers(typeName).ID
End Get
Set(ByVal value As Integer)
CheckIdentifiers()
Dim typeName As String
typeName = Me.GetType.Name
Identifiers(typeName).ID = value
End Set
End Property


So, If I create an object of DerivedType2 and want to cast it as a
BaseType and then get the BaseType.ID property, the above code
executes as DerivedType2 so I get the wrong ID.

Unfortunately, in my test app the DeclaringType is coming up as
Nothing, but thanks for the help. It gives me something to work
on...


Sorry, but I don't understand this. Maybe somebody else can help.


Armin
 
G

Guest

Dinsdale,

I suspect that if you repost this with much more detailed information about
what you are trying to accomplish (including detailed info about the database
structure, etc) then you will get some helpful responses.

As it is, your description is too cryptic for anybody to be of much help.

Kerry Moorman
 
P

Phill W.

Dinsdale said:
The database uses a sequence number for all primary keys in the table
and we are trying to create a class library around it. I didn't want
to have to code derived classes as having base_id, derived_id,
derived_2_id so I've created a collection of identifiers (including
concurrency identifiers such as modified date). Then the lowest base
class has an ID property that looks at the type and returns the
correct Identifier value from the collection for that cast.

/If/ I understand this correctly, you want each derived class to be able
to change the value of the ID that it works with?

That's a job for Overriding.

Class Base
Public Overridable ReadOnly Property ID() as Integer
Get
Return m_iSomeIdentifier
End Get
End Property
End Class

Class Derived
Inherits Base
Public Overrides ReadOnly Property ID() As Integer
Get
Return m_iOtherIdentifier
End Get
End Property
End Class

Now, it doesn't matter what type of variable you put either of the above
into; each works out which Identifier it needs to work with.

(/If/ I understand this correctly ...)

HTH,
Phill W.
 
D

Dinsdale

/If/ I understand this correctly, you want each derived class to be able
to change the value of the ID that it works with?

That's a job for Overriding.

Class Base
Public Overridable ReadOnly Property ID() as Integer
Get
Return m_iSomeIdentifier
End Get
End Property
End Class

Class Derived
Inherits Base
Public Overrides ReadOnly Property ID() As Integer
Get
Return m_iOtherIdentifier
End Get
End Property
End Class

Now, it doesn't matter what type of variable you put either of the above
into; each works out which Identifier it needs to work with.

(/If/ I understand this correctly ...)

HTH,
Phill W.

Phill,

Yes, your understanding is correct (thank you, I didn't want to have
to re-type my original posting!). Unfortunately, I do not get the
results that I was anticipating. regardless of the current cast of the
object, I still get the value from the property of the original
declaring type. Maybe I'm doing something wrong (I hope)?

Module Module1
Public MustInherit Class BaseClass

Public MustOverride Property ID() As Integer

End Class


Public Class Derived1
Inherits BaseClass

Private _derived1Int As Integer
Public Overrides Property ID() As Integer
Get
Return _derived1Int
End Get
Set(ByVal value As Integer)
_derived1Int = value
End Set
End Property


Public Sub New(ByVal der1 As Integer)
_derived1Int = der1
End Sub

End Class

Public Class Derived2
Inherits Derived1

Private _derived2Int As Integer
Public Overrides Property ID() As Integer
Get
Return _derived2Int
End Get
Set(ByVal value As Integer)
_derived2Int = value
End Set
End Property

Public Sub New(ByVal der1 As Integer, ByVal der2 As Integer)
MyBase.New(der1)
_derived2Int = der2
End Sub
End Class

Sub Main()
Dim der2 As New Derived2(12, 3)

Console.WriteLine("The ID from the Derived2 object pointer is: {0}",
der2.ID)

Dim der1 As Derived1

der1 = CType(der2, Derived1) 'The CType call is just for the sake of
being explicit...

Console.WriteLine("The ID from the Derived1 object pointer is: {0}",
der1.ID)

Console.Read()
End Sub


End Module


Any suggestions?

Thanks for all the help!

Dinsdale
 
D

Dinsdale

Phill,

Yes, your understanding is correct (thank you, I didn't want to have
to re-type my original posting!). Unfortunately, I do not get the
results that I was anticipating. regardless of the current cast of the
object, I still get the value from the property of the original
declaring type. Maybe I'm doing something wrong (I hope)?

Module Module1
Public MustInherit Class BaseClass

Public MustOverride Property ID() As Integer

End Class

Public Class Derived1
Inherits BaseClass

Private _derived1Int As Integer
Public Overrides Property ID() As Integer
Get
Return _derived1Int
End Get
Set(ByVal value As Integer)
_derived1Int = value
End Set
End Property

Public Sub New(ByVal der1 As Integer)
_derived1Int = der1
End Sub

End Class

Public Class Derived2
Inherits Derived1

Private _derived2Int As Integer
Public Overrides Property ID() As Integer
Get
Return _derived2Int
End Get
Set(ByVal value As Integer)
_derived2Int = value
End Set
End Property

Public Sub New(ByVal der1 As Integer, ByVal der2 As Integer)
MyBase.New(der1)
_derived2Int = der2
End Sub
End Class

Sub Main()
Dim der2 As New Derived2(12, 3)

Console.WriteLine("The ID from the Derived2 object pointer is: {0}",
der2.ID)

Dim der1 As Derived1

der1 = CType(der2, Derived1) 'The CType call is just for the sake of
being explicit...

Console.WriteLine("The ID from the Derived1 object pointer is: {0}",
der1.ID)

Console.Read()
End Sub

End Module

Any suggestions?

Thanks for all the help!

Dinsdale


Oh, I guess I should post the results and what I expect? lol.

What I was HOPING to get was:

The ID from the Derived2 Object Pointer is: 3
The ID from the Derived1 Object Pointer is: 12

The ACTUAL output was as follows:

The ID from the Derived2 Object Pointer is: 3
The ID from the Derived1 Object Pointer is: 3


Cheers
Dinsdale
 
D

Dinsdale

Oh, I guess I should post the results and what I expect? lol.

What I was HOPING to get was:

The ID from the Derived2 Object Pointer is: 3
The ID from the Derived1 Object Pointer is: 12

The ACTUAL output was as follows:

The ID from the Derived2 Object Pointer is: 3
The ID from the Derived1 Object Pointer is: 3

Cheers
Dinsdale

Ha ha! One of my work mates seems to have solved the problem. The
solution is to use the Shadows keyword. I'll post the explicit
implementation when I figure out how I want to do it...

Thanks everyone!
Dinsdale
 
D

Dinsdale

Ha ha! One of my work mates seems to have solved the problem. The
solution is to use the Shadows keyword. I'll post the explicit
implementation when I figure out how I want to do it...

Thanks everyone!
Dinsdale

Okay, so the following code works and returns the correct values for
the specified object pointer (i.e. Derived2 returns 3, Derived1
returns 12: See previous postings...)

Public MustInherit Class BaseClass

Public MustOverride Property ID() As Integer

End Class

Public Class Derived1
Inherits BaseClass

Private _derived1Int As Integer
Public Overrides Property ID() As Integer
Get

Return _derived1Int

End Get
Set(ByVal value As Integer)
_derived1Int = value
End Set
End Property


Public Sub New(ByVal der1 As Integer)
_derived1Int = der1
End Sub

End Class

Public Class Derived2
Inherits Derived1

Private _derived2Int As Integer
Public Shadows Property ID() As Integer
Get

Return _derived2Int

End Get
Set(ByVal value As Integer)
_derived2Int = value
End Set
End Property

Public Sub New(ByVal der1 As Integer, ByVal der2 As Integer)
MyBase.New(der1)
_derived2Int = der2
End Sub
End Class

This is all very wonderful, but I am essentially a very lazy person
and don't want to have to code all of this for each class. Is there a
way to use reflection to deduce what type of object pointer was used
to call the property from inside the property? If so, I can code this
ONCE in the base class and then use a name value pair collection to
get back the correct value holder as such

Public MustInherit Class BaseClass

Private col1 As New Dictionary(Of String, Integer)

Public Property ID() As Integer
Get
Dim typeName As String
typeName = "?" '? Determine Type Here

Return col1(typeName)
End Get
Set(ByVal value As Integer)

Dim typeName As String
typeName = "?" '? Determine Type Here
col1(typeName) = value
End Set
End Property
End Class

This is over simplified a little as I would need to check for an
instance in the dictionary and that sort of thing, but what seems to
be difficult is to deduce what the object pointer type that called
this property was. Is this possible?

Cheers
Dinsdale
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top