Casting of derived classes

G

Guest

Hello,

I've got a problem and I'm not sure if it is an understanding problem of
class behavior. I searched in the newsgroup and I found some Information
about the same topic, but actually no solution. So sorry for the repost, but
I would glad, if somebody could explain it to me.

/* begin code */
public class a {
}

public class b : a {
}

public class c {

a a_obj = new a();
b b_obj = new b();

// This is the important point
b = (b) a;
}
/* end code */

My problem: In csharp I get a cast Exception. The same thing in VB.NET works
fine. Why is that so and how can I do a workaround?

MfG
Georg Fleischer
 
J

Jon Skeet [C# MVP]

Georg Fleischer said:
I've got a problem and I'm not sure if it is an understanding problem of
class behavior. I searched in the newsgroup and I found some Information
about the same topic, but actually no solution. So sorry for the repost, but
I would glad, if somebody could explain it to me.

/* begin code */
public class a {
}

public class b : a {
}

public class c {

a a_obj = new a();
b b_obj = new b();

// This is the important point
b = (b) a;
}
/* end code */

My problem: In csharp I get a cast Exception. The same thing in VB.NET works
fine. Why is that so and how can I do a workaround?

You should get an exception in VB.NET as well - certainly with Option
Strict On.

If you're not getting an exception, could you post a short but complete
program which demonstrates it?
 
J

Jozsef Bekes

Maybe you want to do this? :
public class c {

a a_obj = new a();
b b_obj;
// This is the important point
b_obj = (b) a;
}

Anyway, the important line seems strange to me:

b = (b) a;
you want to cast an INSTANCE of 'a' into the TYPE (declaration, no instance)
'b'?

Jozsi
 
G

Guest

OK the Option strict was "off" in the visual basic program. I turned it on
and got the same Exception.

But the thing is: How can I assign an object to a class that derived from
the original object class. (See code example)

I got the problem with an extended UserControl in ASP.NET. The Usercontrol
is loaded from am page by Page.LoadControl() and the resulting object should
be passed to an ExtendedUserControl which was derived from that class.
 
J

Jozsef Bekes

Hi

First of all I have almost no experience in C#, I am rather reading than
solving the problems here, but actually this seems to me a problem in the
approach. If we think C++, with virtual functions, you always instanteniate
the derived class, and cast it to the parent. Advantage: you can use
different classes (different in what they do) in the same manner, you can
put them to the same array, call the same function on them. One nice example
is the Paint function - if you paint a button, that is different from
painting a label, still this virtual stuff enables you to invoke the Paint
function of both the button and the label class with the same line of code,
all you need to do is cast both the label and the button into CWnd, and you
can call the Paint just like that. Actually I have never tried to cast the
parent control class (CWnd) to Button, but what would you expect from the
compiler to do for such a cast? What implementation would you put into
Paint()??? So I my opinion is that something might be wrong with what you
try to achieve. But I am no C# expert, others might know more about this
thing....

Jozsi
 
G

Guest

you can't. inheritance simply doesn't work that way. a base can't pretend
to be the derived because it may not have all the functionality of the
derived.
 
G

Guest

Ok. I got the message. Is a another way to reach what I'm looking for?
I got a bizzare idea about assigning all attributes from the new object to
the existing by a collection of attributes. Could I do it like this?:

class b : a
{
void b(a a_obj)
{
foreach(sometype x in a.allements)
{
x = a_obj[x.name];
}
}
}
 
J

Joanna Carter \(TeamB\)

Ok. I got the message. Is a another way to reach what I'm looking for?
I got a bizzare idea about assigning all attributes from the new object to
the existing by a collection of attributes. Could I do it like this?:

class b : a
{
void b(a a_obj)
{
foreach(sometype x in a.allements)
{
x = a_obj[x.name];
}
}
}

What you could do is to implement a copy constructor in the base class and
then call that from the derived class's constructor :

class A
{
...
public A(A other)
{
// copy data members of A here
}
...
}

class B : A
{
...
public B(A aObj) : base(aObj)
{
// any other B constructor stuff
}
}

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
 
J

Jozsef Bekes

Hi

It's the beginner again :)

Here is a nice article (I hope everything is correct in it)

http://www.ondotnet.com/pub/a/dotnet/2002/11/25/copying.html?page=1

It says (end of the first page):
------------------------------------------------------------------------------
Back in the days of C++, this is where so-called "copy constructors" and
"assignment operator overloading" came into play. Now, it's true that in C#
you can define a constructor that looks and feels very much like a C++-style
copy constructor -- and several classes in the FCL do this -- but the truth
is they probably shouldn't bother, because they can't overload the
assignment operator.
Rather, a system-defined interface exists for classes and structs to declare
to the outside world that they support "deep copy" semantics. This interface
is System.ICloneable, and it has a single method: Clone. It doesn't get any
simpler.

---------------------------------------------------------------------

Based on this article it seems to me that ICloneable is to enable customized
copying (deep, or mixture of deep and shallow) of the members, and maybe (I
am not sure, just this is how I see) this interface will not help you with
your problem.

I wonder if this could solve your problem:

a a_obj = new a();

b b_obj = new b();

a a_temp = (a)b_obj();

a_temp = a;

maybe (did not test it, just thought of it) b_obj will be as you wanted. But
I am far not sure... otherwise I cannot see any logical way how you could
access the private members in A. Please let me know if you succeed, I am
very curious :)

Jozsi
 
J

Joanna Carter \(TeamB\)

I tried all the day to get information about ICloneable and copying members
of a class. I found this very interesting article <a
href="http://www.ondotnet.com/lpt/a/2789">Copying, Cloning and Marshalling in
.NET</a>, but it didn't get me further together with your information.

It's part of the .NET documentation under the System namespace.
The point ist, that if I create a derived class to implement the ICloneable
Interface i can't access the private properties of the baseclass. Perhaps I'm
doing something wrong.

Why do you need to get at the private members of a library class ? They are
private because you are not meant to be able to get at them. If you can't do
what you need with the protected and public members, then I'm sorry to tell
you that your design is at fault.

What is it that you need to copy that is private ?

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
 
B

Bruce Wood

Jozset is correct.

I think that you need to post more about what you are trying to do (the
larger problem) and why you want to do it.

Perhaps if we understood more generally what you want to do and why we
could suggest a different solution.
 
J

Jeff Louie

Perhaps the method can return or take the base class where B : A.

A myA= new A();
A myB= new B();

A MyMethod(A someA);

can return new B()!

Hope you understand what I am saying. Thus the generic pattern

object MyMethod(object someObject);

can take and return a reference to an instance of most any class that
derives
from object.

Regards,
Jeff
public class c {

a a_obj = new a();
b b_obj = new b();

// This is the important point
b = (b) a;
}
 
G

Guest

<snip>If we think C++, with virtual functions, you always instanteniate
the derived class, and cast it to the parent<snip>

What you're describing is polymorphism. BUT the derived class inherits
all the methods of the parent class - there's no need to cast it?

If B is derived from A and A has a method foo() then you can call
B.foo() without casting it (assuming foo() is not private). Equally you
can create an list of A objects (ListA) and put B instances in it
without casting. Then later you can retrieve objects from ListA and
call foo() again with no cast - ListA[x].foo().
 
G

Guest

Hello everybody joining then second week of discussing my problem with
derived classes.

Especially I want to thank Joanna for her patience with me :).

This newsgroup-post describes exactly what I want to do, but doesn't help
me, because in my case the described base class "vehicle" is "UserControl" in
"System.Web.UI" Namespace. I have no chance of implementing a copy contructor
to the UserControl class
http://msdn.microsoft.com/newsgroup...harp&mid=0cc2e888-5066-425b-a172-5399ef07740c

That leeds me to the point of despartion. If anybody has an idea, how to
solve this problem, please write.

Best regards,
Georg Fleischer
 
J

Joanna Carter \(TeamB\)

This newsgroup-post describes exactly what I want to do, but doesn't help
me, because in my case the described base class "vehicle" is "UserControl" in
"System.Web.UI" Namespace. I have no chance of implementing a copy contructor
to the UserControl class.
http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.dotnet
..languages.csharp&mid=0cc2e888-5066-425b-a172-5399ef07740c

That leeds me to the point of despartion. If anybody has an idea, how to
solve this problem, please write.

I asked you why you wanted to access private members of UserControl in your
copying routine. What is your answer ?

As was mentioned in the MSDN thread, what you are trying to do is based on
unsound design and until you can justify what you are trying to achieve in
more detail, it is very difficult for anyone to give you an answer that
makes any sense.

The idea of using ICloneable in a derived class also means that you would
have to write a list of assignments of protected or public properties; that
is what cloning is all about, you don't have a choice.

Joanna
 
M

Matt Brandwood

Did you ever get to the bottom of this? Havign built a few apps with
..net I've been working my way through the IBuySpy MS starter kit to get
a better idea of best practice etc.
I've hit seemingly the same stumbling block you did (all be it I'm using
vb.net- so sorry if this post is in teh wrong area). Basically I've got
a custom class that inherits from user control and adds a few extra
properties
ie
Public Class PortalModuleBaseClass
inherits UserControl
Public myname As String
End Class
I then instantiate the class by inserting a usercontrol dynamically into
a panel on the page by using the loadControl method and casting it to
the derived class:
Dim portalModule As PortalModuleBaseClass=
CType(Page.LoadControl(_moduleSettings.DesktopSrc),
PortalModuleBaseClass).

I get the same cast invalid message. What's infuriating is that as far
as I can tell, the same code works for MS in their app.

Any ideas?
 
D

Dave

Sorry, i sent a blank post on accident; hopefully it will be filtered out :)

It seems that you are not specifying the correct path to your custom UserControl:
Dim portalModule As PortalModuleBaseClass=
CType(Page.LoadControl(_moduleSettings.DesktopSrc),
PortalModuleBaseClass).

If "_moduleSettings.DesktopSrc" returns the virtual path to the .ascx file that is "PortalModuleBaseClass : UserControl" then I see
no problem with this code. Ensure that the path is correct, otherwise ensure that this line is throwing the Exception.
 

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