Can anyone help with proper use of operator CType in VB.net?

G

Guest

I'm running into a situation there I think an operator overload would solve
the issue, but I'm unable to make it work for some reason. If anyone can
help here I would appreciate it.

I have a base class that is common to many other classes.
public class Base
....
end class

I have 2 seperate classes that inherit from base

public ClassA : inherits Base
....
End Class

public ClassB : inherits Base
....
End Class

Now, I have an instance of ClassA and ClassB and I'm trying to assign the
ClassB instance to ClassA.

Dim m_ClassA as new ClassA
dim m_ClassB as new ClassB

m_ClassA = m_ClassB

Obviously, this won't work as is because ClassA is not the same as ClassB.
So we turn to operator overloading. I really want to overload the assignment
operator, but I read that VB.Net doesn't support this. So we have to overload
operator CType.

If each ClassA and ClassB have a constructor that takes a string and each
class also had an operator CType that would convert the class instance to a
string, shouldn't the assignment become valid?

public class ClassA inherits Base
public sub New (param as sting)
....
end sub

public shared overloads operator CType(byval obj as ClassA() as string
return obj.ToString()
end sub

end class

If this is not valid, could someone please share what is wrong about this?
the operator CType will compile successfully, but the results are not desired
and the compile still flags it as an error.

unforunately the derived class (ClassA and ClassB) do no know about each
other so we can't put any more specific types into the class definitions.

thanks
bill
 
B

Branco Medeiros

Bill foust wrote:
I have a base class that is common to many other classes.
public class Base
...
end class

I have 2 seperate classes that inherit from base

public ClassA : inherits Base
...
End Class

public ClassB : inherits Base
...
End Class

Now, I have an instance of ClassA and ClassB and I'm trying to assign the
ClassB instance to ClassA.

Dim m_ClassA as new ClassA
dim m_ClassB as new ClassB

m_ClassA = m_ClassB

Obviously, this won't work as is because ClassA is not the same as ClassB.
So we turn to operator overloading. I really want to overload the assignment
operator, but I read that VB.Net doesn't support this. So we have to overload
operator CType.
<snip>

One possible solution would be to have a virtual (Overridable) Assign
method in Base:

Public Overridable Sub Assign(Value As Base)
'...
End Sub

And have each class get from the value whatever they want:

'On ClassB
Public Overrides Sub Assign(Value As Base)
'get items from a Base Class
End Sub

Public Overridable Overloads Sub Assign(Value As ClassB)
Assign(DirectCast(Value, Base))
'get items that are specific for ClassB types
'...
End Sub

'On ClassA
Public Overrides Sub Assign(Value As Base)
'get items from a Base Class
End Sub

Public Overridable Overloads Sub Assign(Value As ClassA)
Assign(DirectCast(Value, Base))
'get items that are specific for ClassA types
'...
End Sub
Dim m_ClassA as new ClassA
dim m_ClassB as new ClassB
m_ClassA.Assign(m_ClassB)

HTH,

Regards

Branco
 
M

Matt

Since both m_ClassA and m_ClassB inherit from Base, then the following
should work:

m_ClassA = DirectCast(m_ClassB, Base)
 
B

Branco Medeiros

Matt said:
Since both m_ClassA and m_ClassB inherit from Base, then the following
should work:

m_ClassA = DirectCast(m_ClassB, Base)
snip>

I guess it won't. In assignment of reference types, a most derived type
may be assigned to a least derived one (in the same inheritance chain,
of course), but not the contrary.

Depending on your Option Strict settings, the compiler may even let you
perform the assignment with nothing but a warning. But, believe me, the
assignment will fail at run time (you certainly don't want to see
that)...

The cast would only be assignable to m_ClassA if m_ClassB derived from
ClassA -- which it doesn't.

Regards,

Branco.
 
G

Guest

Thanks for the quick replies! Unfortunately neither suggestion will work for
me.

I have to use an operator = to do this assignment and cannot use other
methods such as you Assign method. That is unless I'm misunderstanding what
you are saying and Assign() exists on all objects and is used by the compiler
to implement operator=. The help docs didn't seem to suggest that however. :)

You see, Base contains a string of data and the derived classes simply
implement a variety of properties to access specific substring portions of
the string in the class in order to give them a "pretty name". Also, because
this code is the result of an automatic code generation process, it doesnt
really have any knowledge about the types of these derived classes. For these
reasons, I'm kind of stuck using operator = to accomplish both a deep copy
(not a reference copy) and a type cast in one operation.

I was hoping the usage of operator Ctype for a widening to string and
another ctype for widening to the specific class (example below)...

public ClassA : inherits Base
....
public shared overrides widening operator CType(src as ClassA) as string
return src.toString()
end operator
public shared overrides widening operator Ctype(srtc as string) as ClassA
return new ClassA(src)
end operator

would produce an effect similiar to the following...

m_ClassA = new ClassA(m_ClassB.ToString())

Bill
 
J

Jay B. Harlow [MVP - Outlook]

Bill,
| reasons, I'm kind of stuck using operator = to accomplish both a deep copy
| (not a reference copy) and a type cast in one operation.
Why? A square peg (copy/cast) doesn't always fit in a round hole (whatever
you are *actually* attempting to do).


As you show you would need a widening to String, then a narrowing(or
widening) to your specific type.

Unfortunately (or is it fortunately!) VB doesn't apply 2 (user defined)
conversions in a row; Very few languages will apply multiple conversion
operators in a row.

You will need to apply one of the "conversions" manually:

m_ClassA = m_ClassB.ToString()

or

m_ClassA = CStr(m_ClassB)

However!! conversions here really don't feel appropriate!

| You see, Base contains a string of data and the derived classes simply
| implement a variety of properties to access specific substring portions of
| the string in the class in order to give them a "pretty name".
I would consider making ClassA & ClassB strategies that Base uses. ClassA &
ClassB would not have properties as much as a method (possibly a single
method) that given a name returned the value from the string (the substring
portion)...

| Also, because
| this code is the result of an automatic code generation process, it doesnt
| really have any knowledge about the types of these derived classes.
Is it your code generator or someone elses? If its your's it sounds like it
needs to be smarter...

Overall I would step back, look at what the process is really trying to do,
and pick a solution (algorithm) that solves what you are really trying to
do.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Thanks for the quick replies! Unfortunately neither suggestion will work
for
| me.
|
| I have to use an operator = to do this assignment and cannot use other
| methods such as you Assign method. That is unless I'm misunderstanding
what
| you are saying and Assign() exists on all objects and is used by the
compiler
| to implement operator=. The help docs didn't seem to suggest that however.
:)
|
| You see, Base contains a string of data and the derived classes simply
| implement a variety of properties to access specific substring portions of
| the string in the class in order to give them a "pretty name". Also,
because
| this code is the result of an automatic code generation process, it doesnt
| really have any knowledge about the types of these derived classes. For
these
| reasons, I'm kind of stuck using operator = to accomplish both a deep copy
| (not a reference copy) and a type cast in one operation.
|
| I was hoping the usage of operator Ctype for a widening to string and
| another ctype for widening to the specific class (example below)...
|
| public ClassA : inherits Base
| ...
| public shared overrides widening operator CType(src as ClassA) as string
| return src.toString()
| end operator
| public shared overrides widening operator Ctype(srtc as string) as ClassA
| return new ClassA(src)
| end operator
|
| would produce an effect similiar to the following...
|
| m_ClassA = new ClassA(m_ClassB.ToString())
|
| Bill
|
|
| "Branco Medeiros" wrote:
|
| > Bill foust wrote:
| > <snip>
| > > I have a base class that is common to many other classes.
| > > public class Base
| > > ...
| > > end class
| > >
| > > I have 2 seperate classes that inherit from base
| > >
| > > public ClassA : inherits Base
| > > ...
| > > End Class
| > >
| > > public ClassB : inherits Base
| > > ...
| > > End Class
| > >
| > > Now, I have an instance of ClassA and ClassB and I'm trying to assign
the
| > > ClassB instance to ClassA.
| > >
| > > Dim m_ClassA as new ClassA
| > > dim m_ClassB as new ClassB
| > >
| > > m_ClassA = m_ClassB
| > >
| > > Obviously, this won't work as is because ClassA is not the same as
ClassB.
| > > So we turn to operator overloading. I really want to overload the
assignment
| > > operator, but I read that VB.Net doesn't support this. So we have to
overload
| > > operator CType.
| > <snip>
| >
| > One possible solution would be to have a virtual (Overridable) Assign
| > method in Base:
| >
| > Public Overridable Sub Assign(Value As Base)
| > '...
| > End Sub
| >
| > And have each class get from the value whatever they want:
| >
| > 'On ClassB
| > Public Overrides Sub Assign(Value As Base)
| > 'get items from a Base Class
| > End Sub
| >
| > Public Overridable Overloads Sub Assign(Value As ClassB)
| > Assign(DirectCast(Value, Base))
| > 'get items that are specific for ClassB types
| > '...
| > End Sub
| >
| > 'On ClassA
| > Public Overrides Sub Assign(Value As Base)
| > 'get items from a Base Class
| > End Sub
| >
| > Public Overridable Overloads Sub Assign(Value As ClassA)
| > Assign(DirectCast(Value, Base))
| > 'get items that are specific for ClassA types
| > '...
| > End Sub
| >
| > > Dim m_ClassA as new ClassA
| > > dim m_ClassB as new ClassB
| > >
| > m_ClassA.Assign(m_ClassB)
| >
| > HTH,
| >
| > Regards
| >
| > Branco
| >
| >
 
B

Branco Medeiros

Bill foust wrote:
I have to use an operator = to do this assignment and cannot use other
methods such as you Assign method. That is unless I'm misunderstanding what
you are saying and Assign() exists on all objects and is used by the compiler
to implement operator=. The help docs didn't seem to suggest that however. :)

Ha! That would be so conveninent! =))
You see, Base contains a string of data and the derived classes simply
implement a variety of properties to access specific substring portions of
the string in the class in order to give them a "pretty name". Also, because
this code is the result of an automatic code generation process, it doesnt
really have any knowledge about the types of these derived classes. For these
reasons, I'm kind of stuck using operator = to accomplish both a deep copy
(not a reference copy) and a type cast in one operation.
<snip>

But it seems you have access to the classes definitions, though,
otherwise how could you 'append' the implementation of the CType
converter...?

In this case, why don't you have:

In class A
Shared Widening Operator CType(ByVal Other As B) As A
Dim Text As String = 'Gets Text from B
Return New A(Text)
End Operator

In class B
Shared Widening Operator CType(ByVal Other As A) As B
Dim Text As String = 'Gets Text from A
Return New B(Text)
End Operator

Regards,

Branco.
 

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