473,387 Members | 1,575 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Polymorphism

Hi!

I'm struggling a bit with Polymorphism in vb.net. There is something I know
I can do in C++, but I cannot seem to do it in vb.net (or c# for that
matter).

Basically, I have an abstract base class that deals with adding, deleting,
editing another class.

I have written an implementation of that class, and also a derived version
of the 'managed' class - so effectively my derived version manages a
specialised version of whatever the base one does. However, the compiler
complains that I havent implemented the MustInherit methods...

To explain a bit better...
Public Class CMessage
' This is the "managed" class

Public MustInherit Class CMessageManager
' This is the abstract base class
Public MustOverride Function MessageReceived (ByRef objMessage As
CMessage) As Boolean

Public Class CEmail Inherits CMessage
' Derived version

Public Class CEmailMessageManager Inherits CMessageManager
' Implemented version - want it to deal with emails

Public MustOverride Function MessageReceived (ByRef objMessage As CEmail)
As Boolean
' Pass in an email and deal with it
This concept is supported by C++ - it must be possible to do it in .NET, but
I really dont know how.

Any help would be greatly appreciated!


Nov 20 '05 #1
30 1966
In article <O$**************@TK2MSFTNGP09.phx.gbl>, Richard Tappenden wrote:
Hi!

I'm struggling a bit with Polymorphism in vb.net. There is something I know
I can do in C++, but I cannot seem to do it in vb.net (or c# for that
matter).

Basically, I have an abstract base class that deals with adding, deleting,
editing another class.

I have written an implementation of that class, and also a derived version
of the 'managed' class - so effectively my derived version manages a
specialised version of whatever the base one does. However, the compiler
complains that I havent implemented the MustInherit methods...

To explain a bit better...
Public Class CMessage
' This is the "managed" class

Public MustInherit Class CMessageManager
' This is the abstract base class
Public MustOverride Function MessageReceived (ByRef objMessage As
CMessage) As Boolean

Public Class CEmail Inherits CMessage
' Derived version

Public Class CEmailMessageManager Inherits CMessageManager
' Implemented version - want it to deal with emails

Public MustOverride Function MessageReceived (ByRef objMessage As CEmail)
As Boolean
' Pass in an email and deal with it
This concept is supported by C++ - it must be possible to do it in .NET, but
I really dont know how.

Any help would be greatly appreciated!


I'm not sure what the problem is - the compiler is telling you exactly
what the problem is... If you want to be able to use
CEmailMessageManager then you must override the MessageReceived
function..

Public Class CEmailMessageManager Inherits CMessageManager

Public Overrides Function MessageReceived (ByRef objMessage As
CEmail) As Boolean
' Do stuff
End Function
End Class

Even in C++ this is the rule. You can't use a function that has no
implementation. The rules for using Abstract base classes are pretty
much the same in VB.NET as the are in C++.
--
Tom Shelton
MVP [Visual Basic]
Nov 20 '05 #2
Hi Tom,

Thanks for the reply - but I think you've misunderstood the question - I'm
well aware that I can create an instance of an abstract class etc...

The problem is that I cant seem to override the base class methods unless
they all use the base message class to do the operations - i.e:

The base class method =
Public MustOverride Function MessageReceived (ByRef objMessage As CMessage)
As Boolean

My derived version
Public Overrides Function MessageReceived(ByRef objMessage As CEmailMessage)
As Boolean
' Do something
End Function.

The overridden version complains - stating that I still need to override
MessageReceived(ByRef objMessage CMessage) As Boolean.

In C++, you can do this - i.e. it resolves the virtual table correctly.

For example - check these c++ files...(apologies if they don't look nice, I
knocked them up quickly to prove the point)

"Tom Shelton" <to*@mtogden.com> wrote in message
news:uQ**************@TK2MSFTNGP09.phx.gbl...
In article <O$**************@TK2MSFTNGP09.phx.gbl>, Richard Tappenden

wrote:
Hi!

I'm struggling a bit with Polymorphism in vb.net. There is something I know I can do in C++, but I cannot seem to do it in vb.net (or c# for that
matter).

Basically, I have an abstract base class that deals with adding, deleting, editing another class.

I have written an implementation of that class, and also a derived version of the 'managed' class - so effectively my derived version manages a
specialised version of whatever the base one does. However, the compiler
complains that I havent implemented the MustInherit methods...

To explain a bit better...
Public Class CMessage
' This is the "managed" class

Public MustInherit Class CMessageManager
' This is the abstract base class
Public MustOverride Function MessageReceived (ByRef objMessage As
CMessage) As Boolean

Public Class CEmail Inherits CMessage
' Derived version

Public Class CEmailMessageManager Inherits CMessageManager
' Implemented version - want it to deal with emails

Public MustOverride Function MessageReceived (ByRef objMessage As CEmail) As Boolean
' Pass in an email and deal with it
This concept is supported by C++ - it must be possible to do it in .NET, but I really dont know how.

Any help would be greatly appreciated!


I'm not sure what the problem is - the compiler is telling you exactly
what the problem is... If you want to be able to use
CEmailMessageManager then you must override the MessageReceived
function..

Public Class CEmailMessageManager Inherits CMessageManager

Public Overrides Function MessageReceived (ByRef objMessage As
CEmail) As Boolean
' Do stuff
End Function
End Class

Even in C++ this is the rule. You can't use a function that has no
implementation. The rules for using Abstract base classes are pretty
much the same in VB.NET as the are in C++.
--
Tom Shelton
MVP [Visual Basic]







Nov 20 '05 #3
"Richard Tappenden" <ri******@mailkey.com> schrieb
The problem is that I cant seem to override the base class methods
unless they all use the base message class to do the operations -
i.e:

The base class method =
Public MustOverride Function MessageReceived (ByRef objMessage As
CMessage) As Boolean

My derived version
Public Overrides Function MessageReceived(ByRef objMessage As
CEmailMessage) As Boolean
' Do something
End Function.

The overridden version complains - stating that I still need to
override MessageReceived(ByRef objMessage CMessage) As Boolean.
The derived class must contain a procedure with the same signature. In your
case, the signature is different because the type of the argument is
CEmailMessage, not CMessage as in the base class.
In C++, you can do this - i.e. it resolves the virtual table
correctly.

For example - check these c++ files...(apologies if they don't look
nice, I knocked them up quickly to prove the point)

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #4
In article <u1**************@TK2MSFTNGP09.phx.gbl>, Richard Tappenden wrote:
Hi Tom,

Thanks for the reply - but I think you've misunderstood the question - I'm
well aware that I can create an instance of an abstract class etc...

The problem is that I cant seem to override the base class methods unless
they all use the base message class to do the operations - i.e:

The base class method =
Public MustOverride Function MessageReceived (ByRef objMessage As CMessage)
As Boolean

My derived version
Public Overrides Function MessageReceived(ByRef objMessage As CEmailMessage)
As Boolean
' Do something
End Function.

The overridden version complains - stating that I still need to override
MessageReceived(ByRef objMessage CMessage) As Boolean.


Aah, now I understand and Armin hit the nail on the head. You have not
overridden the base function because the sig does not match. You are
passing a CEmailMessage - not CMessage, which is what the base class
defines.

--
Tom Shelton
MVP [Visual Basic]
Nov 20 '05 #5
Hi Armin.

Thanks for the reply - I understand what you are saying, however the
CEmailMessage class is derived from CMessage - so it should work (at least
it does work that way in C++)

"Armin Zingler" <az*******@freenet.de> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
The problem is that I cant seem to override the base class methods
unless they all use the base message class to do the operations -
i.e:

The base class method =
Public MustOverride Function MessageReceived (ByRef objMessage As
CMessage) As Boolean

My derived version
Public Overrides Function MessageReceived(ByRef objMessage As
CEmailMessage) As Boolean
' Do something
End Function.

The overridden version complains - stating that I still need to
override MessageReceived(ByRef objMessage CMessage) As Boolean.
The derived class must contain a procedure with the same signature. In

your case, the signature is different because the type of the argument is
CEmailMessage, not CMessage as in the base class.
In C++, you can do this - i.e. it resolves the virtual table
correctly.

For example - check these c++ files...(apologies if they don't look
nice, I knocked them up quickly to prove the point)

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #6
Richard,
..NET is not C++! Remember C++ also supports Multiple Inheritance where as
..NET does not.

C++ allows for covariant parameters, however .NET (the CLR itself) does not
allow for covariant parameters.

I understand that you can use Eiffel for .NET http://www.eiffel.com/ and
have covariant parameters, however you will not be able to use that code
with C# or VB.NET, as it is not CLS complient...

Hope this helps
Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:ui**************@TK2MSFTNGP11.phx.gbl...
Hi Armin.

Thanks for the reply - I understand what you are saying, however the
CEmailMessage class is derived from CMessage - so it should work (at least
it does work that way in C++)

<<snip>>
Nov 20 '05 #7
"Richard Tappenden" <ri******@mailkey.com> schrieb

Thanks for the reply - I understand what you are saying, however
the CEmailMessage class is derived from CMessage - so it should work
(at least it does work that way in C++)


In .NET, the signatures must match exactly. I haven't thought about why they
have to (yet).
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #8
"Armin Zingler" <az*******@freenet.de> schrieb
"Richard Tappenden" <ri******@mailkey.com> schrieb

Thanks for the reply - I understand what you are saying, however
the CEmailMessage class is derived from CMessage - so it should
work (at least it does work that way in C++)


In .NET, the signatures must match exactly. I haven't thought about
why they have to (yet).


Now I did. ;-)

If I am the author of the base class, I want to force the author(s) of the
derived class(es) to accept *any* CMessage object. If you change the
signature to CEMailMessage, you break this enforcement because not any
CMessage object can be passed anymore.
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #9
That really defeats the point of OO programming - remember the CEmailMessage
is "a kind of" CMessage object - therefore I should be able to pass it into
the base class method - and it will do anything with it that it could with a
CMessage.

If I then implement a more complete, specific kind of message object and a
manager class that deals with them as well - it should be able to take
advantage of the new improved class, and yet still be "a kind of" base
object.

I must say, I'm pretty disappointed that this hasn't been put into .NET, and
I really think it will make a few things difficult when moving code over
from C++ to C#.

Incidently, in C++ I think you can enforce types by using the Explicit
keyword, which would restrict the types as per your idea below.
If I am the author of the base class, I want to force the author(s) of the
derived class(es) to accept *any* CMessage object. If you change the
signature to CEMailMessage, you break this enforcement because not any
CMessage object can be passed anymore.

Nov 20 '05 #10
"Richard Tappenden" <ri******@mailkey.com> schrieb
That really defeats the point of OO programming - remember the
CEmailMessage is "a kind of" CMessage object - therefore I should be
able to pass it into the base class method - and it will do anything
with it that it could with a CMessage.


CEMailMessage is a kind of CMessage object, but not every CMessage object is
a CEMailMessage object.

Imagine, you derive another class from CMessage:

class CNewsMessage
inherits CMessage
end class

The author of the base class wants that *any* kind of CMessage
object can be passed to the procedure. If you change the signature to
CEMailMessage, a CNewsMessage object can *not* be passed - although it *is*
a kind of CMessage object. This would brake the rule defined in the base
class.
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #11
Sorry Armin, I dont think you quite understand the concept...

The base class would take any kind (lets pretend has been implemented...)

If someone writes a specialised version of that base class, they are more
than entitled to state that the method requires a specialised version of the
parameter (especially seeing as they could be several levels up in the
heirarchy).

The derived one could still pass the method down to the base implementation,
because anything you could do with the base one, you can do with the derived
one (because we are talking object oriented programming). The derived one
could then perform any additional or different processing with the more
advanced one.

It should be down to the derived class to decide whether it wants to use a
derived version or not - the base class should not specify this.

So in your example, a CEmailManager would only want CEmailMessages - it wont
accept CNewsMessage. Another class would have to be written (CNewsManager)
to explicitly deal with news messages, because they have to have slightly
different code inside (for example in an email you might want to filter its
content for spam, but a news message you might not want to).

Any filtering/processing that could be done on a CMessage could be written
in the base class, so...

CMessageManager -
Sub MessageReceived(msg As CMessage)
' Do sommat
End Sub

CEMailManager
Sub MessageReceived(msg As CEmailMessage)
MyBase.MessageReceived(msg)
FilterForSpam(msg)
End Sub

CNewsManager
Sub MessageReceived(msg As CNewsMessage)
MyBase.MessageReceived(msg)
AcceptMessage(msg)
End Sub

"Armin Zingler" <az*******@freenet.de> wrote in message
news:OH**************@TK2MSFTNGP12.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
That really defeats the point of OO programming - remember the
CEmailMessage is "a kind of" CMessage object - therefore I should be
able to pass it into the base class method - and it will do anything
with it that it could with a CMessage.
CEMailMessage is a kind of CMessage object, but not every CMessage object

is a CEMailMessage object.

Imagine, you derive another class from CMessage:

class CNewsMessage
inherits CMessage
end class

The author of the base class wants that *any* kind of CMessage
object can be passed to the procedure. If you change the signature to
CEMailMessage, a CNewsMessage object can *not* be passed - although it *is* a kind of CMessage object. This would brake the rule defined in the base
class.
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #12
"Richard Tappenden" <ri******@mailkey.com> schrieb
Sorry Armin, I dont think you quite understand the concept...
I think *you* don't understand it - but don't let us start this...
The base class would take any kind (lets pretend has been
implemented...)

If someone writes a specialised version of that base class, they are
more than entitled to state that the method requires a specialised
version of the parameter (especially seeing as they could be several
levels up in the heirarchy).
Yes, you can add overloaded versions, but you still have to implement the
version with the same signature as in the base class - it is declared as
MustOverride.
The derived one could still pass the method down to the base
implementation, because anything you could do with the base one, you
can do with the derived one (because we are talking object oriented
programming). The derived one could then perform any additional or
different processing with the more advanced one.

It should be down to the derived class to decide whether it wants to
use a derived version or not - the base class should not specify
this.
Yes again, the derived classes might have overloaded versions that accept
specialized (=derived) objects. Even if you don't add overloaded versions,
you can pass objects derived from the base class. That's called
"polymorphism" as mentioned in the subject.
So in your example, a CEmailManager would only want CEmailMessages -
it wont accept CNewsMessage. Another class would have to be written
(CNewsManager) to explicitly deal with news messages, because they
have to have slightly different code inside (for example in an email
you might want to filter its content for spam, but a news message you
might not want to).

Any filtering/processing that could be done on a CMessage could be
written in the base class, so...

CMessageManager -
Sub MessageReceived(msg As CMessage)
' Do sommat
End Sub

CEMailManager
Sub MessageReceived(msg As CEmailMessage)
MyBase.MessageReceived(msg)
FilterForSpam(msg)
End Sub

CNewsManager
Sub MessageReceived(msg As CNewsMessage)
MyBase.MessageReceived(msg)
AcceptMessage(msg)
End Sub


This example shows the right usage of polymorphism: You can pass a CMessage
object or any object derived from CMessage to
CMessageManager.MessageReceived. As the method is not declared as
MustOverride, you are not forced to override it in the derived classes.

Further more, I can only repeat myself: As the method in CMessageManager is
declared as MustOverride, you must override it in the derived class. The
base class' author wants the author of the derived class
to write a method that accepts *any* type of CMessage object. What does
"any" mean? It means that the type of the passed object can be CMessage or
derived from CMessage. Now, if you would limit it to CEmailMessage objects,
you can not pass a CNewsMessage object. But why? CNewsMessage is derived
from CMessage, so it must work. Consequently you can not create this
limitation.

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #13
Richard,
That really defeats the point of OO programming - Some would say that not supporting Multiple Inheritance would also defeat
the point of OO programming... ;-) But as Armin stated, lets not go there!
;-)

I'm really not sure why .NET does not support Covariant return types &
parameters. I find them useful in some cases. There was a discussion about
this a year and a half to two years ago, where someone pointed to a web site
about why covariant return types & parameters "don't work" however I do not
have that link handy.
I must say, I'm pretty disappointed that this hasn't been put into .NET, and I really think it will make a few things difficult when moving code over
from C++ to C#. Rather then moving to C#, have you considered Managed C++? I have not used
Managed C++ enough to know if it preserved covariant return types &
parameters or not (for managed classes). I understand that Eiffel .NET
supports them. Just be aware there are .NET languages that support covariant
return types & parameters, however they are not required to interop with
other languages...

Hope this helps
Jay
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... That really defeats the point of OO programming - remember the CEmailMessage is "a kind of" CMessage object - therefore I should be able to pass it into the base class method - and it will do anything with it that it could with a CMessage.

If I then implement a more complete, specific kind of message object and a
manager class that deals with them as well - it should be able to take
advantage of the new improved class, and yet still be "a kind of" base
object.

I must say, I'm pretty disappointed that this hasn't been put into .NET, and I really think it will make a few things difficult when moving code over
from C++ to C#.

Incidently, in C++ I think you can enforce types by using the Explicit
keyword, which would restrict the types as per your idea below.
If I am the author of the base class, I want to force the author(s) of the derived class(es) to accept *any* CMessage object. If you change the
signature to CEMailMessage, you break this enforcement because not any
CMessage object can be passed anymore.


Nov 20 '05 #14
Hi Jay,

Funnily enough, I dont miss multiple inheritance much :-)

I have used it in a few cases, but only because we were to lazy to
encapsulate the second class that it derived from - tbh multiple inheritance
is a very powerful tool, but it requires a very thorough design. Bad
implementation of this causes serious problems.

However, I think with what I am requesting, it can actually really help the
structure of the software - especially if you are creating a heirarchical,
easily deployable and updatable solution.

Still, never mind. I'll put the base types in the prototypes, and case them
to the ones I require.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eb**************@TK2MSFTNGP12.phx.gbl...
Richard,
That really defeats the point of OO programming - Some would say that not supporting Multiple Inheritance would also defeat
the point of OO programming... ;-) But as Armin stated, lets not go there!
;-)

I'm really not sure why .NET does not support Covariant return types &
parameters. I find them useful in some cases. There was a discussion about
this a year and a half to two years ago, where someone pointed to a web

site about why covariant return types & parameters "don't work" however I do not have that link handy.
I must say, I'm pretty disappointed that this hasn't been put into .NET, and
I really think it will make a few things difficult when moving code over
from C++ to C#.

Rather then moving to C#, have you considered Managed C++? I have not used
Managed C++ enough to know if it preserved covariant return types &
parameters or not (for managed classes). I understand that Eiffel .NET
supports them. Just be aware there are .NET languages that support

covariant return types & parameters, however they are not required to interop with
other languages...

Hope this helps
Jay
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
That really defeats the point of OO programming - remember the CEmailMessage
is "a kind of" CMessage object - therefore I should be able to pass it

into
the base class method - and it will do anything with it that it could with a
CMessage.

If I then implement a more complete, specific kind of message object and a manager class that deals with them as well - it should be able to take
advantage of the new improved class, and yet still be "a kind of" base
object.

I must say, I'm pretty disappointed that this hasn't been put into .NET,

and
I really think it will make a few things difficult when moving code over
from C++ to C#.

Incidently, in C++ I think you can enforce types by using the Explicit
keyword, which would restrict the types as per your idea below.
If I am the author of the base class, I want to force the author(s) of

the derived class(es) to accept *any* CMessage object. If you change the
signature to CEMailMessage, you break this enforcement because not any
CMessage object can be passed anymore.



Nov 20 '05 #15
Armin & Richard,
Sorry Armin, I dont think you quite understand the concept... I think *you* don't understand it - but don't let us start this...


This reminds me of the story of three blind men who stumble upon an elephant
and are attempting to describe it... ;-) I get the impression all three of
use understand, we are just describing a different part of the same animal!

Armin: You do realize that Richard is referring to Covariant return types &
parameters, which is an advanced OO technique that simple is not available
on .NET? Although I think you're close to why it doesn't always work in
practice, or why it doesn't always work as you would expect.

Personally Covariant return types & parameters are similar to Multiple
Inheritance. They are not available in .NET, I can live with that. It would
be nice, in some cases if they were available, but they are not, life goes
on. The only real workaround, that I know of, is as Armin & I suggested
overloads and/or runtime type checking.

This is similar to Generics: today they are not available, however with
Whidbey they will be available.

Maybe if enough people submit a MS Wish then in .NET 3.0 or 4.0 we may get
covariant return types & parameters. Of course MS may have really good
technical reasons on why they are not supported, unfortunately I do not know
what those technical reasons are. I do know that it will make the work of
the JIT a little more challenging. ;-) Either way I understand that Eiffel
..NET supports both MI & Covariants today, if you are willing to stay within
Eiffel .NET.

Richard: Have you considered submitting a request to MS Wish, requesting
that Covariant return types & parameters be supported in .NET?
http://register.microsoft.com/mswish/suggestion.asp

Hope this helps
Jay

"Armin Zingler" <az*******@freenet.de> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl... "Richard Tappenden" <ri******@mailkey.com> schrieb
Sorry Armin, I dont think you quite understand the concept...
I think *you* don't understand it - but don't let us start this...
The base class would take any kind (lets pretend has been
implemented...)

If someone writes a specialised version of that base class, they are
more than entitled to state that the method requires a specialised
version of the parameter (especially seeing as they could be several
levels up in the heirarchy).


Yes, you can add overloaded versions, but you still have to implement the
version with the same signature as in the base class - it is declared as
MustOverride.
The derived one could still pass the method down to the base
implementation, because anything you could do with the base one, you
can do with the derived one (because we are talking object oriented
programming). The derived one could then perform any additional or
different processing with the more advanced one.

It should be down to the derived class to decide whether it wants to
use a derived version or not - the base class should not specify
this.


Yes again, the derived classes might have overloaded versions that accept
specialized (=derived) objects. Even if you don't add overloaded versions,
you can pass objects derived from the base class. That's called
"polymorphism" as mentioned in the subject.
So in your example, a CEmailManager would only want CEmailMessages -
it wont accept CNewsMessage. Another class would have to be written
(CNewsManager) to explicitly deal with news messages, because they
have to have slightly different code inside (for example in an email
you might want to filter its content for spam, but a news message you
might not want to).

Any filtering/processing that could be done on a CMessage could be
written in the base class, so...

CMessageManager -
Sub MessageReceived(msg As CMessage)
' Do sommat
End Sub

CEMailManager
Sub MessageReceived(msg As CEmailMessage)
MyBase.MessageReceived(msg)
FilterForSpam(msg)
End Sub

CNewsManager
Sub MessageReceived(msg As CNewsMessage)
MyBase.MessageReceived(msg)
AcceptMessage(msg)
End Sub


This example shows the right usage of polymorphism: You can pass a

CMessage object or any object derived from CMessage to
CMessageManager.MessageReceived. As the method is not declared as
MustOverride, you are not forced to override it in the derived classes.

Further more, I can only repeat myself: As the method in CMessageManager is declared as MustOverride, you must override it in the derived class. The
base class' author wants the author of the derived class
to write a method that accepts *any* type of CMessage object. What does
"any" mean? It means that the type of the passed object can be CMessage or
derived from CMessage. Now, if you would limit it to CEmailMessage objects, you can not pass a CNewsMessage object. But why? CNewsMessage is derived
from CMessage, so it must work. Consequently you can not create this
limitation.

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #16
Hi Jay & Armin,

Thanks to both of you for your help with this.

I'm going to have to live with the fact that VB.NET doesn't support this
functionality.

I will submit the wish - lets hope it gets in.

Cheers again,

Richard

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Ob****************@TK2MSFTNGP12.phx.gbl...
Armin & Richard,
Sorry Armin, I dont think you quite understand the concept... I think *you* don't understand it - but don't let us start this...


This reminds me of the story of three blind men who stumble upon an

elephant and are attempting to describe it... ;-) I get the impression all three of use understand, we are just describing a different part of the same animal!
Armin: You do realize that Richard is referring to Covariant return types & parameters, which is an advanced OO technique that simple is not available
on .NET? Although I think you're close to why it doesn't always work in
practice, or why it doesn't always work as you would expect.

Personally Covariant return types & parameters are similar to Multiple
Inheritance. They are not available in .NET, I can live with that. It would be nice, in some cases if they were available, but they are not, life goes
on. The only real workaround, that I know of, is as Armin & I suggested
overloads and/or runtime type checking.

This is similar to Generics: today they are not available, however with
Whidbey they will be available.

Maybe if enough people submit a MS Wish then in .NET 3.0 or 4.0 we may get
covariant return types & parameters. Of course MS may have really good
technical reasons on why they are not supported, unfortunately I do not know what those technical reasons are. I do know that it will make the work of
the JIT a little more challenging. ;-) Either way I understand that Eiffel
.NET supports both MI & Covariants today, if you are willing to stay within Eiffel .NET.

Richard: Have you considered submitting a request to MS Wish, requesting
that Covariant return types & parameters be supported in .NET?
http://register.microsoft.com/mswish/suggestion.asp

Hope this helps
Jay

"Armin Zingler" <az*******@freenet.de> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
Sorry Armin, I dont think you quite understand the concept...


I think *you* don't understand it - but don't let us start this...
The base class would take any kind (lets pretend has been
implemented...)

If someone writes a specialised version of that base class, they are
more than entitled to state that the method requires a specialised
version of the parameter (especially seeing as they could be several
levels up in the heirarchy).


Yes, you can add overloaded versions, but you still have to implement the version with the same signature as in the base class - it is declared as
MustOverride.
The derived one could still pass the method down to the base
implementation, because anything you could do with the base one, you
can do with the derived one (because we are talking object oriented
programming). The derived one could then perform any additional or
different processing with the more advanced one.

It should be down to the derived class to decide whether it wants to
use a derived version or not - the base class should not specify
this.


Yes again, the derived classes might have overloaded versions that accept specialized (=derived) objects. Even if you don't add overloaded versions, you can pass objects derived from the base class. That's called
"polymorphism" as mentioned in the subject.
So in your example, a CEmailManager would only want CEmailMessages -
it wont accept CNewsMessage. Another class would have to be written
(CNewsManager) to explicitly deal with news messages, because they
have to have slightly different code inside (for example in an email
you might want to filter its content for spam, but a news message you
might not want to).

Any filtering/processing that could be done on a CMessage could be
written in the base class, so...

CMessageManager -
Sub MessageReceived(msg As CMessage)
' Do sommat
End Sub

CEMailManager
Sub MessageReceived(msg As CEmailMessage)
MyBase.MessageReceived(msg)
FilterForSpam(msg)
End Sub

CNewsManager
Sub MessageReceived(msg As CNewsMessage)
MyBase.MessageReceived(msg)
AcceptMessage(msg)
End Sub


This example shows the right usage of polymorphism: You can pass a

CMessage
object or any object derived from CMessage to
CMessageManager.MessageReceived. As the method is not declared as
MustOverride, you are not forced to override it in the derived classes.

Further more, I can only repeat myself: As the method in CMessageManager

is
declared as MustOverride, you must override it in the derived class. The
base class' author wants the author of the derived class
to write a method that accepts *any* type of CMessage object. What does
"any" mean? It means that the type of the passed object can be CMessage or derived from CMessage. Now, if you would limit it to CEmailMessage

objects,
you can not pass a CNewsMessage object. But why? CNewsMessage is derived
from CMessage, so it must work. Consequently you can not create this
limitation.

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html


Nov 20 '05 #17
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> schrieb
I do
know that it will make the work of the JIT a little more challenging.
;-)


Hehe :)

(my only contribution as my knowledge is exhausted in this case :) )
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #18
In article <#f**************@TK2MSFTNGP09.phx.gbl>, Armin Zingler wrote:
"Richard Tappenden" <ri******@mailkey.com> schrieb
Sorry Armin, I dont think you quite understand the concept...
I think *you* don't understand it - but don't let us start this...
The base class would take any kind (lets pretend has been
implemented...)


<snip>
from CMessage, so it must work. Consequently you can not create this
limitation.


Armin,

I think what Richard is getting at is that C++ lets you specialize the
parameter type. In other words, you can create classes that derive from
the base, but only accept as parameters a specific subclass.

That doesn't sound clear to me... Basically, he's saying is that in his
example you have the base message type and a base message manager...

Public MustInherit Class BaseMessage
Public MustOverride Sub SendMessage(ByVal Text As String)
End Class

Public MustInherit Class BaseMsgManager
Public MustOverride Sub ProcessMessage(ByVal Message As BaseMessage)
End Class

From that you can create specialized types to deal with specific
subclasses...

Public Class SnailMail
Inherits BaseMessage

Public Overrides Sub SendMessage(ByVal Text As String)
Call PayPostage()
Call PutInMailBox()
End Sub
End Class

Public Class SnailMailManager
Public Overrides Sub ProcessMessage(ByVal Message As SnailMail)
Message.SendMessage("Hello, World!")
End Sub
End Class

In C++, you are createing a specialized version of the manager class
that will only deal with a specific subclass of BaseMessage. You can't
do that directly in .NET. What Richard could do is something like:
Public Class SnailMailManager
Public Overrides Sub ProcessMessage(ByVal Message As BaseMessage)
If TypeOf Message Is SnailMail Then
Me.ProcessMessage(DirectCast(Message, SnailMail))
Else
Throw New ArgumentException("Type of Message Must Be
SnailMail)
End If
End Sub
Public Overloads Sub ProcessMessage(ByVal Message As SnailMail)
Message.SendMessage("Hello, World!")
End Sub

End Class
Though that does seem a little extra work for something that some
languages do automatically.
--
Tom Shelton
MVP [Visual Basic]
Nov 20 '05 #19
Cor
Hi Jay,
Sorry Armin, I dont think you quite understand the concept...

I think *you* don't understand it - but don't let us start this...


This reminds me of the story of three blind men who stumble upon an

elephant

what those technical reasons are. I do know that it will make the work of
"that elephant" a little more challenging.

:-))

I was just reading it, not what you where all talking about, I show you only
my laugh on my face when I was reading your words about the elephant. (and
the elephant has no meaning I don't know if it is a challange)

Cor
Nov 20 '05 #20
Hi Armin,

What can I say! I had a good think about this last night (sad, I should have
been drinking or something), and I realised that everything you said about
Abstract classes makes perfect sense.

So, I'll have to look at another way of doing it :D

Thanks again for your help,

Richard
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:Og**************@TK2MSFTNGP09.phx.gbl...
Hi Jay & Armin,

Thanks to both of you for your help with this.

I'm going to have to live with the fact that VB.NET doesn't support this
functionality.

I will submit the wish - lets hope it gets in.

Cheers again,

Richard

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:Ob****************@TK2MSFTNGP12.phx.gbl...
Armin & Richard,
> Sorry Armin, I dont think you quite understand the concept...
I think *you* don't understand it - but don't let us start this...
This reminds me of the story of three blind men who stumble upon an

elephant
and are attempting to describe it... ;-) I get the impression all three

of
use understand, we are just describing a different part of the same

animal!

Armin: You do realize that Richard is referring to Covariant return types &
parameters, which is an advanced OO technique that simple is not available on .NET? Although I think you're close to why it doesn't always work in
practice, or why it doesn't always work as you would expect.

Personally Covariant return types & parameters are similar to Multiple
Inheritance. They are not available in .NET, I can live with that. It would
be nice, in some cases if they were available, but they are not, life goes on. The only real workaround, that I know of, is as Armin & I suggested
overloads and/or runtime type checking.

This is similar to Generics: today they are not available, however with
Whidbey they will be available.

Maybe if enough people submit a MS Wish then in .NET 3.0 or 4.0 we may get covariant return types & parameters. Of course MS may have really good
technical reasons on why they are not supported, unfortunately I do not

know
what those technical reasons are. I do know that it will make the work of the JIT a little more challenging. ;-) Either way I understand that Eiffel .NET supports both MI & Covariants today, if you are willing to stay

within
Eiffel .NET.

Richard: Have you considered submitting a request to MS Wish, requesting
that Covariant return types & parameters be supported in .NET?
http://register.microsoft.com/mswish/suggestion.asp

Hope this helps
Jay

"Armin Zingler" <az*******@freenet.de> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
> Sorry Armin, I dont think you quite understand the concept...

I think *you* don't understand it - but don't let us start this...

> The base class would take any kind (lets pretend has been
> implemented...)
>
> If someone writes a specialised version of that base class, they are
> more than entitled to state that the method requires a specialised
> version of the parameter (especially seeing as they could be several
> levels up in the heirarchy).

Yes, you can add overloaded versions, but you still have to implement the version with the same signature as in the base class - it is declared as MustOverride.

> The derived one could still pass the method down to the base
> implementation, because anything you could do with the base one, you
> can do with the derived one (because we are talking object oriented
> programming). The derived one could then perform any additional or
> different processing with the more advanced one.
>
> It should be down to the derived class to decide whether it wants to
> use a derived version or not - the base class should not specify
> this.

Yes again, the derived classes might have overloaded versions that accept specialized (=derived) objects. Even if you don't add overloaded versions, you can pass objects derived from the base class. That's called
"polymorphism" as mentioned in the subject.

> So in your example, a CEmailManager would only want CEmailMessages -
> it wont accept CNewsMessage. Another class would have to be written
> (CNewsManager) to explicitly deal with news messages, because they
> have to have slightly different code inside (for example in an email
> you might want to filter its content for spam, but a news message you > might not want to).
>
> Any filtering/processing that could be done on a CMessage could be
> written in the base class, so...
>
> CMessageManager -
> Sub MessageReceived(msg As CMessage)
> ' Do sommat
> End Sub
>
> CEMailManager
> Sub MessageReceived(msg As CEmailMessage)
> MyBase.MessageReceived(msg)
> FilterForSpam(msg)
> End Sub
>
> CNewsManager
> Sub MessageReceived(msg As CNewsMessage)
> MyBase.MessageReceived(msg)
> AcceptMessage(msg)
> End Sub

This example shows the right usage of polymorphism: You can pass a

CMessage
object or any object derived from CMessage to
CMessageManager.MessageReceived. As the method is not declared as
MustOverride, you are not forced to override it in the derived classes.
Further more, I can only repeat myself: As the method in CMessageManager is
declared as MustOverride, you must override it in the derived class.
The base class' author wants the author of the derived class
to write a method that accepts *any* type of CMessage object. What does "any" mean? It means that the type of the passed object can be CMessage or derived from CMessage. Now, if you would limit it to CEmailMessage

objects,
you can not pass a CNewsMessage object. But why? CNewsMessage is

derived from CMessage, so it must work. Consequently you can not create this
limitation.

--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html



Nov 20 '05 #21
"Richard Tappenden" <ri******@mailkey.com> schrieb
Hi Armin,

What can I say! I had a good think about this last night (sad, I
should have been drinking or something), and I realised that
everything you said about Abstract classes makes perfect sense.

So, I'll have to look at another way of doing it :D

Thanks again for your help,


Huh? I'm still trying to understand Tom Shelton's posting, and you are
saying that I was right? :-))))
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #22
Hi Armin -

The confusion is with the abstract bit. What I was asking for is essentialy
what VB does with the Overloads stuff.

In C++, you simply do this

Class CBase
{
virtual void DoSomething( CBaseObj obj );
}

void
CBase::DoSomething(CBaseObj obj)
{
// Do Something
}

Class CDerived
{
virtual void DoSomething( CDerivedObj obj );
}

void
CDerived::DoSomething(CDerivedObj obj)
{
// Do something different
}

But of course, if the base method had been abstract it wouldn't make sense.
I was just being a little blind :-)

I think Tom & Jay were both explaining how I can do the above, or possibly
that I could do something similar(ish) with abstract method

i.e. I could do this

Class CBase
{
virtual CBaseObj GetObj() = 0;
}

Class CDerived
{
virtual CBaseObj GetObj();
}

CBaseObj
CDerived::GetObj()
{
CDerivedObj derivedObj;
return derivedObj;
}

Sorry for all the confusion!

Richard

"Armin Zingler" <az*******@freenet.de> wrote in message
news:e1**************@TK2MSFTNGP12.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
Hi Armin,

What can I say! I had a good think about this last night (sad, I
should have been drinking or something), and I realised that
everything you said about Abstract classes makes perfect sense.

So, I'll have to look at another way of doing it :D

Thanks again for your help,


Huh? I'm still trying to understand Tom Shelton's posting, and you are
saying that I was right? :-))))
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #23
Richard,
Yes Tom & I were describing Covariant parameter types, along with some
alternative methods that you can use in .NET instead, which Armin also
described.
But of course, if the base method had been abstract it wouldn't make sense. I was just being a little blind :-) In C++, if the method is abstract, you can still have covariant parameters.
Class CBase
virtual void DoSomething( CBaseObj obj ) = 0;
Class CDerived
virtual void DoSomething( CDerivedObj obj );
Only CDerived::DoSomething needs an implementation to compile. (verified
with unmanaged code, not tested with managed code).

In .NET you cannot have covariant parameters whether they are abstract or
not.
Class CBase
{
virtual CBaseObj GetObj() = 0;
} Your template method is a fair alternative.

Hope this helps
Jay
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:OP**************@tk2msftngp13.phx.gbl... Hi Armin -

The confusion is with the abstract bit. What I was asking for is essentialy what VB does with the Overloads stuff.

In C++, you simply do this

Class CBase
{
virtual void DoSomething( CBaseObj obj );
}

void
CBase::DoSomething(CBaseObj obj)
{
// Do Something
}

Class CDerived
{
virtual void DoSomething( CDerivedObj obj );
}

void
CDerived::DoSomething(CDerivedObj obj)
{
// Do something different
}

But of course, if the base method had been abstract it wouldn't make sense. I was just being a little blind :-)

I think Tom & Jay were both explaining how I can do the above, or possibly
that I could do something similar(ish) with abstract method

i.e. I could do this

Class CBase
{
virtual CBaseObj GetObj() = 0;
}

Class CDerived
{
virtual CBaseObj GetObj();
}

CBaseObj
CDerived::GetObj()
{
CDerivedObj derivedObj;
return derivedObj;
}

Sorry for all the confusion!

Richard

"Armin Zingler" <az*******@freenet.de> wrote in message
news:e1**************@TK2MSFTNGP12.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
Hi Armin,

What can I say! I had a good think about this last night (sad, I
should have been drinking or something), and I realised that
everything you said about Abstract classes makes perfect sense.

So, I'll have to look at another way of doing it :D

Thanks again for your help,


Huh? I'm still trying to understand Tom Shelton's posting, and you are
saying that I was right? :-))))
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html


Nov 20 '05 #24
Hi Jay,

I looked into the C++ thing, it does compile, but I dont think you'll be
able to create an instance of the derived object.

This is what threw me off the scent before, because VB.NET would not
compile - but in C++ the derived class would still be considered abstract,
so it isn't a compilation error at that point - only when you try to
instantiate it.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
Richard,
Yes Tom & I were describing Covariant parameter types, along with some
alternative methods that you can use in .NET instead, which Armin also
described.
But of course, if the base method had been abstract it wouldn't make sense.
I was just being a little blind :-)

In C++, if the method is abstract, you can still have covariant

parameters.
Class CBase
virtual void DoSomething( CBaseObj obj ) = 0;


Class CDerived
virtual void DoSomething( CDerivedObj obj );


Only CDerived::DoSomething needs an implementation to compile. (verified
with unmanaged code, not tested with managed code).

In .NET you cannot have covariant parameters whether they are abstract or
not.
Class CBase
{
virtual CBaseObj GetObj() = 0;
}

Your template method is a fair alternative.

Hope this helps
Jay
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:OP**************@tk2msftngp13.phx.gbl...
Hi Armin -

The confusion is with the abstract bit. What I was asking for is

essentialy
what VB does with the Overloads stuff.

In C++, you simply do this

Class CBase
{
virtual void DoSomething( CBaseObj obj );
}

void
CBase::DoSomething(CBaseObj obj)
{
// Do Something
}

Class CDerived
{
virtual void DoSomething( CDerivedObj obj );
}

void
CDerived::DoSomething(CDerivedObj obj)
{
// Do something different
}

But of course, if the base method had been abstract it wouldn't make

sense.
I was just being a little blind :-)

I think Tom & Jay were both explaining how I can do the above, or possibly that I could do something similar(ish) with abstract method

i.e. I could do this

Class CBase
{
virtual CBaseObj GetObj() = 0;
}

Class CDerived
{
virtual CBaseObj GetObj();
}

CBaseObj
CDerived::GetObj()
{
CDerivedObj derivedObj;
return derivedObj;
}

Sorry for all the confusion!

Richard

"Armin Zingler" <az*******@freenet.de> wrote in message
news:e1**************@TK2MSFTNGP12.phx.gbl...
"Richard Tappenden" <ri******@mailkey.com> schrieb
> Hi Armin,
>
> What can I say! I had a good think about this last night (sad, I
> should have been drinking or something), and I realised that
> everything you said about Abstract classes makes perfect sense.
>
> So, I'll have to look at another way of doing it :D
>
> Thanks again for your help,

Huh? I'm still trying to understand Tom Shelton's posting, and you are
saying that I was right? :-))))
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html



Nov 20 '05 #25
Richard,
Hmm...

My mistake, C++ only supports Covariant return types, not covariant
parameters.

http://msdn.microsoft.com/msdnmag/is...C/default.aspx

I wonder if Whidbey C++ supports Covariant parameters? Or I just remember
that the C++ spec supports them. Either way Visual C++ does not...

Sample of Covariant return type:

class CBase
{
virtual CBaseObj* DoSomething() = 0;
}

class CDerived : public CBase
{
virtual CDerivedObj* DoSomething();
}

With Visual C++ 7.1 you can compile & create a CDerived object. (helps if I
verify you can create the object ;-))

In an earlier post Armin stated something, that I think is partially as to
why Covariant parameters won't work, or at least don't work the way you
would expect...

My mistake for thinking Visual C++ supported Covariant parameters...

Of course with overloading you can get the effect of covariant parameters.

Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:uq**************@TK2MSFTNGP09.phx.gbl...
Hi Jay,

I looked into the C++ thing, it does compile, but I dont think you'll be
able to create an instance of the derived object.

This is what threw me off the scent before, because VB.NET would not
compile - but in C++ the derived class would still be considered abstract,
so it isn't a compilation error at that point - only when you try to
instantiate it.

Nov 20 '05 #26
Hi Jay,

Thats exactly where I went wrong - I just checked that it compiled :-)

I've redesigned the solution now - the base class has an implementation, and
throws an error if it is called. Its not quite a nice as it would have been
(because being abstract it would have forced an implementation higher up),
but at least if it throws an error, we'll soon realise that the specialised
version hasn't been written.

Another question though -

I have something like this:

CBase
Function DoSomething( ByRef myObj CBaseObj)
'Blah
End Function

CDerived
Function DoSomethingElse(ByRef myObj As CDerivedObj)
MyBase.DoSomething(myObj)
End Function

This doesn't work - it asks me to cast the CDerivedObj to a CBaseObj.
However, if I change DoSomethingElse to be passed in ByVal, it works ok. It
isn't really a problem, but I am just curious as to the reason...

Thanks again for your help!

Richard

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:um**************@TK2MSFTNGP12.phx.gbl...
Richard,
Hmm...

My mistake, C++ only supports Covariant return types, not covariant
parameters.

http://msdn.microsoft.com/msdnmag/is...C/default.aspx

I wonder if Whidbey C++ supports Covariant parameters? Or I just remember
that the C++ spec supports them. Either way Visual C++ does not...

Sample of Covariant return type:

class CBase
{
virtual CBaseObj* DoSomething() = 0;
}

class CDerived : public CBase
{
virtual CDerivedObj* DoSomething();
}

With Visual C++ 7.1 you can compile & create a CDerived object. (helps if I verify you can create the object ;-))

In an earlier post Armin stated something, that I think is partially as to
why Covariant parameters won't work, or at least don't work the way you
would expect...

My mistake for thinking Visual C++ supported Covariant parameters...

Of course with overloading you can get the effect of covariant parameters.

Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:uq**************@TK2MSFTNGP09.phx.gbl...
Hi Jay,

I looked into the C++ thing, it does compile, but I dont think you'll be
able to create an instance of the derived object.

This is what threw me off the scent before, because VB.NET would not
compile - but in C++ the derived class would still be considered abstract, so it isn't a compilation error at that point - only when you try to
instantiate it.


Nov 20 '05 #27
Richard,
Function DoSomething( ByRef myObj CBaseObj) I believe you are confusing ByVal & ByRef Parameters with Value & Reference
Types.

My standard FAQ on ByVal & ByRef verses Value Types & Reference Types
(Knowing C++ I'm sure you know allot of this, except maybe not in the
context of VB.NET):

ByVal & ByRef Parameters are independent of Reference & Value Types. All
parameters by default are passed ByVal, you should only pass a parameter
ByRef when you have to, which is when you need to modify the callers
variable.

Less memory use & better performance should not be a factor in choosing
ByVal & ByRef. The only time to consider ByRef for less memory & performance
is when passing large structures (structures as in defined with the
Structure keyword), however structures should never be large!

Structure Usage Guidelines.
http://msdn.microsoft.com/library/de...guidelines.asp

A Reference Type is an object that exists on the heap. If I have a variable
that is a reference type and assign the variable to another variable. Both
variables will be pointing to the same object on the heap.

Dim x As Person
x = New Person()
Dim y As Person
y = x

Both x & y are the exact same Person object on the heap.

A Value Type does not live on the Heap. If I have a value type variable and
I assign it to another variable, a copy of the value is made.

Dim x As Integer
x = 100
Dim y As Integer
y = x

Although both x & y have the value 100, they are physically different values
as a copy was made.

Now when you pass a variable to a ByVal parameter a copy of the variable is
made. So for a Reference Type a copy of the reference is made, which means
there is still only one object on the heap & two references to that object.
For a Value Type a copy of the value is made.

When you pass a variable to a ByRef parameter a reference to that variable
is made. So for a Reference Type you have a reference to a reference to the
object, for a Value Type you have a reference to the value.

Remember ByVal & ByRef are how parameters are passed. Reference & Value
Types are how quantities are stored.

Hope this helps
Jay
"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:e2**************@TK2MSFTNGP12.phx.gbl... Hi Jay,

Thats exactly where I went wrong - I just checked that it compiled :-)

I've redesigned the solution now - the base class has an implementation, and throws an error if it is called. Its not quite a nice as it would have been (because being abstract it would have forced an implementation higher up),
but at least if it throws an error, we'll soon realise that the specialised version hasn't been written.

Another question though -

I have something like this:

CBase
Function DoSomething( ByRef myObj CBaseObj)
'Blah
End Function

CDerived
Function DoSomethingElse(ByRef myObj As CDerivedObj)
MyBase.DoSomething(myObj)
End Function

This doesn't work - it asks me to cast the CDerivedObj to a CBaseObj.
However, if I change DoSomethingElse to be passed in ByVal, it works ok. It isn't really a problem, but I am just curious as to the reason...

Thanks again for your help!

Richard

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:um**************@TK2MSFTNGP12.phx.gbl...
Richard,
Hmm...

My mistake, C++ only supports Covariant return types, not covariant
parameters.

http://msdn.microsoft.com/msdnmag/is...C/default.aspx

I wonder if Whidbey C++ supports Covariant parameters? Or I just remember
that the C++ spec supports them. Either way Visual C++ does not...

Sample of Covariant return type:

class CBase
{
virtual CBaseObj* DoSomething() = 0;
}

class CDerived : public CBase
{
virtual CDerivedObj* DoSomething();
}

With Visual C++ 7.1 you can compile & create a CDerived object. (helps if
I
verify you can create the object ;-))

In an earlier post Armin stated something, that I think is partially as

to why Covariant parameters won't work, or at least don't work the way you
would expect...

My mistake for thinking Visual C++ supported Covariant parameters...

Of course with overloading you can get the effect of covariant parameters.
Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:uq**************@TK2MSFTNGP09.phx.gbl...
Hi Jay,

I looked into the C++ thing, it does compile, but I dont think you'll be able to create an instance of the derived object.

This is what threw me off the scent before, because VB.NET would not
compile - but in C++ the derived class would still be considered

abstract, so it isn't a compilation error at that point - only when you try to
instantiate it.



Nov 20 '05 #28
Hi Jay,

Thanks for the info - I did realise that you passed ByRef so you can change
the values, and only recently found out that they are no more efficient
(where as in C++ it is 'heaps' (sorry, couldn't resist) more efficient).
Obviously if you didnt want the value changed, you'd pass it in as a const
ref.

I'm still not 100% sure why I cannot pass a derived object through as a base
object if it is ByRef, but I guess there must be a good reason for it :-)

Cheers,

Richard

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:e9**************@tk2msftngp13.phx.gbl...
Richard,
Function DoSomething( ByRef myObj CBaseObj) I believe you are confusing ByVal & ByRef Parameters with Value &

Reference Types.

My standard FAQ on ByVal & ByRef verses Value Types & Reference Types
(Knowing C++ I'm sure you know allot of this, except maybe not in the
context of VB.NET):

ByVal & ByRef Parameters are independent of Reference & Value Types. All
parameters by default are passed ByVal, you should only pass a parameter
ByRef when you have to, which is when you need to modify the callers
variable.

Less memory use & better performance should not be a factor in choosing
ByVal & ByRef. The only time to consider ByRef for less memory & performance is when passing large structures (structures as in defined with the
Structure keyword), however structures should never be large!

Structure Usage Guidelines.
http://msdn.microsoft.com/library/de...guidelines.asp
A Reference Type is an object that exists on the heap. If I have a variable that is a reference type and assign the variable to another variable. Both
variables will be pointing to the same object on the heap.

Dim x As Person
x = New Person()
Dim y As Person
y = x

Both x & y are the exact same Person object on the heap.

A Value Type does not live on the Heap. If I have a value type variable and I assign it to another variable, a copy of the value is made.

Dim x As Integer
x = 100
Dim y As Integer
y = x

Although both x & y have the value 100, they are physically different values as a copy was made.

Now when you pass a variable to a ByVal parameter a copy of the variable is made. So for a Reference Type a copy of the reference is made, which means
there is still only one object on the heap & two references to that object. For a Value Type a copy of the value is made.

When you pass a variable to a ByRef parameter a reference to that variable
is made. So for a Reference Type you have a reference to a reference to the object, for a Value Type you have a reference to the value.

Remember ByVal & ByRef are how parameters are passed. Reference & Value
Types are how quantities are stored.

Hope this helps
Jay

Nov 20 '05 #29
Richard,
I'm still not 100% sure why I cannot pass a derived object through as a base object if it is ByRef, but I guess there must be a good reason for it :-) ByRef by definition implies that the called routine can modify the calling
routines variable. Think will modify calling routine variable! The called
routine can assign any object that derives from its parameter type to the
ByRef parameter.

Option Strict On, prevents implicit conversions, you need to explicitly give
the conversion...

Consider the following:
I have something like this:

CBase
Function DoSomething( ByRef myObj CBaseObj) myObj = New COtherObj () End Function

CDerived : inherits CBase
Function DoSomethingElse(ByRef myObj As CDerivedObj)
MyBase.DoSomething(myObj)
End Function
COtherObj : inherits CBaseObj
Dim derived As New CDerived
derived.DoSomethingElse

Notice that CBase.DoSomething can 'return' (via the ByRef parameter) a
COtherObj, as COtherObj inherits from CBaseObj. However CDerived cannot put
a COtherObj into a CDerivedObj variable as COtherObj does not inherit from
CDerivedObj.
Obviously if you didnt want the value changed, you'd pass it in as a const
ref. As you know "const-ness" is a C++ feature that is not found in .NET, you
could always use MS wish to send a request for it ;-)

Hope this helps
Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... Hi Jay,

Thanks for the info - I did realise that you passed ByRef so you can change the values, and only recently found out that they are no more efficient
(where as in C++ it is 'heaps' (sorry, couldn't resist) more efficient).
Obviously if you didnt want the value changed, you'd pass it in as a const
ref.

I'm still not 100% sure why I cannot pass a derived object through as a base object if it is ByRef, but I guess there must be a good reason for it :-)

Cheers,

Richard

Nov 20 '05 #30
Hi Jay,

That kinda makes sense I suppose - although if you do get it as the base
version, I dont see why you shouldn't be able to change any base properties
of the parameter.

I might do the wish thing, but MS might end up getting fed up with me :D

Richard.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Richard,
I'm still not 100% sure why I cannot pass a derived object through as a base
object if it is ByRef, but I guess there must be a good reason for it :-) ByRef by definition implies that the called routine can modify the calling
routines variable. Think will modify calling routine variable! The called
routine can assign any object that derives from its parameter type to the
ByRef parameter.

Option Strict On, prevents implicit conversions, you need to explicitly give the conversion...

Consider the following:
I have something like this:

CBase
Function DoSomething( ByRef myObj CBaseObj) myObj = New COtherObj ()
End Function

CDerived : inherits CBase
Function DoSomethingElse(ByRef myObj As CDerivedObj)
MyBase.DoSomething(myObj)
End Function


COtherObj : inherits CBaseObj
Dim derived As New CDerived
derived.DoSomethingElse

Notice that CBase.DoSomething can 'return' (via the ByRef parameter) a
COtherObj, as COtherObj inherits from CBaseObj. However CDerived cannot

put a COtherObj into a CDerivedObj variable as COtherObj does not inherit from
CDerivedObj.
Obviously if you didnt want the value changed, you'd pass it in as a

const ref.

As you know "const-ness" is a C++ feature that is not found in .NET, you
could always use MS wish to send a request for it ;-)

Hope this helps
Jay

"Richard Tappenden" <ri******@mailkey.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi Jay,

Thanks for the info - I did realise that you passed ByRef so you can

change
the values, and only recently found out that they are no more efficient
(where as in C++ it is 'heaps' (sorry, couldn't resist) more efficient).
Obviously if you didnt want the value changed, you'd pass it in as a const ref.

I'm still not 100% sure why I cannot pass a derived object through as a

base
object if it is ByRef, but I guess there must be a good reason for it :-)
Cheers,

Richard


Nov 20 '05 #31

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

37
by: Mike Meng | last post by:
hi all, I'm a newbie Python programmer with a C++ brain inside. I have a lightweight framework in which I design a base class and expect user to extend. In other part of the framework, I heavily...
18
by: Ken | last post by:
Hi. Can anyone refer me to any articles about the compatibility between c++ polymorphism and real-time programming? I'm currently on a real-time c++ project, and we're having a discussion...
3
by: E. Robert Tisdale | last post by:
polymorph just means "many form(s)". The definition in plain English http://www.bartleby.com/61/66/P0426600.html and narrower definitions in the context of computer programming ...
11
by: richard pickworth | last post by:
Can anyone explain polymorphism?(very simply). thanks richard
4
by: LP | last post by:
Hi, I understand the concept/definition of polymorphism. But what does the term "runtime polymorphism" mean? I was asked to define it during a technical interview. I gave a guy vanilla definition...
13
by: Krivenok Dmitry | last post by:
Hello all! Perhaps the most important feature of dynamic polymorphism is ability to handle heterogeneous collections of objects. ("C++ Templates: The Complete Guide" by David Vandevoorde and...
18
by: Seigfried | last post by:
I have to write a paper about object oriented programming and I'm doing some reading to make sure I understand it. In a book I'm reading, however, polymorphism is defined as: "the ability of two...
2
by: sarathy | last post by:
Hi all, I need a small clarification reg. Templates and Polymorphism. I believe templates is really a good feature, which can be used to implement generic functions and classes. But i doubt...
11
by: chsalvia | last post by:
I've been programming in C++ for a little over 2 years, and I still find myself wondering when I should use polymorphism. Some people claim that polymorphism is such an integral part of C++,...
17
by: Bart Friederichs | last post by:
Hello, I created the following inheritance: class Parent { public: void foo(int i); }; class Child : public Parent {
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.