473,698 Members | 2,261 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C# inheritance broken?

C# is an impressive language...but it seems to have one big limitation
that, from a C++ background, seems unacceptable.

Here's the problem:

I have a third-party Document class. (This means I can't change the
Document class.) I want to extend this (inherit from Document) as
MyDocument, adding new events and application-specific methods and
properties.

I submit that this can't be done in C#.

Consider this example:

class MyDocument : public Document

This doesn't work because the only way to open an existing Document is
using the static method Document.Load(s tring FileName), which returns a
Document object. There doesn't seem to be any way to convert or cast a
Document object to a MyDocument object. There is therefore no way to
"Load" a MyDocument object!
>From reading LOTS of posts on this group, the standard answers are:
1. "Wrap" the object, as follows:
class MyDocument
{
protected Document TheDocument;
}

But...this means that I have to wrap EACH of the hundreds of methods
and properties needed to manipulate the Document object. This is
clearly a case for inheritance, to allow the base class properties and
methods to be automatically available, with enhancements from the
derived class.

2. In MyDocument.Load , call Document.Load, and then COPY all of
Document's members to MyDocument.

BUT, this is prohibitive because COPYING all of Document's members is
prohibitive in terms of run time, and also in terms of development
effort (lines of code, and therefore, potential bugs).

In C++, I would do something like this:

class MyDocument : public Document
{
public static MyDocument Load(string FileName)
{
return (MyDocument)Doc ument.Load(File Name);
}
}

So my conclusion is that C# inheritance is broken (in practice) because
of its strict type-checking, and no allowance for such a common
scenario.

Did I miss something?

Jan 26 '07
64 3451
Mark,

Yes, reinterpret_cas t is indeed unsafe. But if there are no added
members, it works, as in CRect : RECT.

But this strays from what I'm hoping to accomplish.

How is it that serialization can magically create a Document object
through casting an "object" to "Document," but I'm not allowed to use
the same trick to create a MyDocument instead? The Serialization
classes don't know about Document while deserialization is occuring,
but it still lets you cast the return value of Deserialize into a
Document type. What is the trick they are using?

Tony

On Jan 26, 2:30 pm, "Mark Wilden" <mwil...@commun itymtm.comwrote :
<gro...@isaacso ft.comwrote in messagenews:11* *************** ******@k78g2000 cwa.googlegroup s.com...
As I pointed out before, C++
does indeed allow you to write such a "helper" class; you can use
reinterpret_cas t to transform Document into a MyDocument.Is this quite true? My understanding is that <reinterpret_ca stsimply
performs an explicitly unsafe case of a pointer. It doesn't transform
anything. In this case, if a Document is created, it can never be
"transforme d" into another type.

///ark
Jan 26 '07 #21


On Jan 26, 12:53 pm, gro...@isaacsof t.com wrote:
Mark,

Yes, reinterpret_cas t is indeed unsafe. But if there are no added
members, it works, as in CRect : RECT.

But this strays from what I'm hoping to accomplish.

How is it that serialization can magically create a Document object
through casting an "object" to "Document," but I'm not allowed to use
the same trick to create a MyDocument instead?
Because .NET doesn't trust you. :-)

One of the goals of .NET was to produce code that was immune to the
sort of run-time memory hacking that is rampant in C and C++. If the
runtime lets you play tricks like reinterpret_cas t, then the code can't
be verifiably safe, can it?

As I said in my other post: different design goals. One goal of C++ was
to give the programmer total power to do whatever he wants, and the
compiler will trust him to get it right (by generating code no matter
what it might do at runtime). One goal of C# is to produce only code
that can be verified to not clobber memory / reinterpret memory
patterns as that which they are not / etc.

The two design goals are, obviously, incompatible.

If you want to do this sort of thing in C#, you have to use the
"unsafe" keyword to tell the compiler / runtime to lay off, but even
then I'm not sure of just how far you can go with that, because I've
never used it.

Jan 26 '07 #22
Hi,

<gr****@isaacso ft.comwrote in message
news:11******** **************@ s48g2000cws.goo glegroups.com.. .
| >You build it of course ;-)
|
| Hmmm...I'm not sure how that would happen. I'm still stuck with the
| fact that the third-party component's Load method returns a Document,
| which can't be converted to type MyDocument, even in DocumentLoader.

You simply have a crappy component :)
Use other
--
Ignacio Machin
machin AT laceupsolutions com
Jan 26 '07 #23
Hi,

"Michael D. Ober" <obermd.@.alum. mit.edu.nospamw rote in message
news:45******** *************@n ews.qwest.net.. .

| --
| Ignacio Machin
| machin AT laceupsolutions com
| >
| This isn't a C# issue. It is a dotNet issue as I have run into the same
| issue of inheriting a base class (in my case, VB 2005 and
StringCollectio n)
| and providing a method for the base class object to become the object at
the
| heart of the derived class.

Not at all, A base class cannot become a derived class, A derived class can
be treated as a base class without any problem.

Think about, what would hppen if the derived object add a new property,
clearly the base does not has it , so what can the compiler do in this
case??

| This is a design limitation in the framework

No, it's simply bad design of the base class, or trying to made a bad use of
the class.

Jan 26 '07 #24


On Jan 26, 11:36 am, "Michael D. Ober" <obermd.@.alum. mit.edu.nospam>
wrote:
"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions .comwrote in
messagenews:%2* **************@ TK2MSFTNGP06.ph x.gbl...
Hi,
"Mythran" <kip_pot...@hot mail.comwrote in message
news:e8******** ******@TK2MSFTN GP04.phx.gbl...
|
|
| <gro...@isaacso ft.comwrote in message
|news:11******* *************** @v45g2000cwv.go oglegroups.com. ..
| Ignacio,
| >
| Thank you for your thoughts.
| >
| The Document class does have a public default constructor, and it is
| not sealed. I have no problem creating a "new" Document object, or a
| "new" MyDocument object, for that matter. What I can't do is
"convert"
| an existing Document object (such as the one returned by
Document.Load)
| into a MyDocument.
As I said in another post, giving the struct you are presenting you would
have the same issue no matter what language you use. You cannot treat a
base
class as a derived class, you can do the opposite though.
In your case you will have to implement your own Load method. I would
first
check though if Document provide a Load method instance. or maybe a Clone
method
--
Ignacio Machin
machin AT laceupsolutions comThis isn't a C# issue. It is a dotNet issue as I have run into the same
issue of inheriting a base class (in my case, VB 2005 and StringCollectio n)
and providing a method for the base class object to become the object at the
heart of the derived class. This is a design limitation in the framework
itself. From a business logic perspective, it should be doable.
For the record, no language that I know of lets you do this. C++ allows
you to pretend to do it via an unsafe cast, but you're not really
getting a derived object, just playing with a base class object as
though it were a derived object, which is fodder for disaster unless
you keep careful track of what you're doing.

You can't use a base class instance as though it were a derived class
instance because the latter may have more fields than the former, and
so the base class instance doesn't have enough space to store the state
of the derived class.

There _are_ various strategies for using a base class instance as a
model for creating a derived class. Most of them, however, require some
coding. There's no "automatic" way of copying state from one instance
to another, which might be a nice addition.

Jan 27 '07 #25
On 26 Jan 2007 12:26:15 -0800, gr****@isaacsof t.com wrote:
>Here is some more relevant information that I've just learned:

The Document.Load static method relies on System.Runtime. Serialization
to create a new Document object. Formatter.Deser ialize returns an
object that is a Document, and this Document object can't be cast to a
MyDocument. Deserialization can't occur in a constructor, because the
Document object already exists, and you can't replace "this" with the
new Document object.

So it would seem that the limitation is there because of the way
serializatio n works, not because of a bad design on the part of the
author of Document.

Tony
Taking a completely different tack, how easy would it be for you to
parse through the Serialized Document file and change it to whatever
the equivalent Serialized MyDocument file would look like?

Given that you are trying to upcast the derived class, which goes
against the design goals of C#, this might be an easier way to work
round your problem.

rossum

Jan 27 '07 #26
No, it's simply bad design of the base class, or trying to made a bad use of
the class.
OK, please enlighten me. What would be the proper design of the base
class? I see no way to inherit from such a base class, regardless of
the base class design!

Tony

On Jan 26, 4:44 pm, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
laceupsolutions .comwrote:
Hi,

"Michael D. Ober" <obermd.@.alum. mit.edu.nospamw rote in messagenews:45* *************** *****@news.qwes t.net...

| --
| Ignacio Machin
| machin AT laceupsolutions com
| >
| This isn't a C# issue. It is a dotNet issue as I have run into the same
| issue of inheriting a base class (in my case, VB 2005 and
StringCollectio n)
| and providing a method for the base class object to become the object at
the
| heart of the derived class.

Not at all, A base class cannot become a derived class, A derived class can
be treated as a base class without any problem.

Think about, what would hppen if the derived object add a new property,
clearly the base does not has it , so what can the compiler do in this
case??

| This is a design limitation in the framework

No, it's simply bad design of the base class, or trying to made a bad use of
the class.
Jan 27 '07 #27

"Bruce Wood" <br*******@cana da.comwrote in message
news:11******** **************@ a75g2000cwd.goo glegroups.com.. .
>

On Jan 26, 11:36 am, "Michael D. Ober" <obermd.@.alum. mit.edu.nospam>
wrote:
>"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions .comwrote
in
messagenews:%2 *************** @TK2MSFTNGP06.p hx.gbl...
Hi,
"Mythran" <kip_pot...@hot mail.comwrote in message
news:e8******* *******@TK2MSFT NGP04.phx.gbl.. .
|
|
| <gro...@isaacso ft.comwrote in message
|news:11******* *************** @v45g2000cwv.go oglegroups.com. ..
| Ignacio,
| >
| Thank you for your thoughts.
| >
| The Document class does have a public default constructor, and it
is
| not sealed. I have no problem creating a "new" Document object, or
a
| "new" MyDocument object, for that matter. What I can't do is
"convert"
| an existing Document object (such as the one returned by
Document.Load)
| into a MyDocument.
As I said in another post, giving the struct you are presenting you
would
have the same issue no matter what language you use. You cannot treat a
base
class as a derived class, you can do the opposite though.
In your case you will have to implement your own Load method. I would
first
check though if Document provide a Load method instance. or maybe a
Clone
method
--
Ignacio Machin
machin AT laceupsolutions comThis isn't a C# issue. It is a dotNet
issue as I have run into the same
issue of inheriting a base class (in my case, VB 2005 and
StringCollecti on)
and providing a method for the base class object to become the object at
the
heart of the derived class. This is a design limitation in the framework
itself. From a business logic perspective, it should be doable.

For the record, no language that I know of lets you do this. C++ allows
you to pretend to do it via an unsafe cast, but you're not really
getting a derived object, just playing with a base class object as
though it were a derived object, which is fodder for disaster unless
you keep careful track of what you're doing.

You can't use a base class instance as though it were a derived class
instance because the latter may have more fields than the former, and
so the base class instance doesn't have enough space to store the state
of the derived class.

There _are_ various strategies for using a base class instance as a
model for creating a derived class. Most of them, however, require some
coding. There's no "automatic" way of copying state from one instance
to another, which might be a nice addition.
A generalized method of converting a base class into a derived class with
the knowledge that the derived class may still require some initialization
would definitely be useful, even if you had to do it via a constructor that
takes an object of the base class as it's argument. The missing syntax, in
vb is

mybase = objBaseClass

In C# I think it would be

base = objBaseClass

In either case, since this is occurring in a constructor in place of the
base.New() or mybase.New statement, the programmer knows he still has to
instantiate and initialize all other private and protected objects in the
derived class.

Mike Ober.

Jan 27 '07 #28
<gr****@isaacso ft.comwrote:
No, it's simply bad design of the base class, or trying to made a bad use of
the class.

OK, please enlighten me. What would be the proper design of the base
class? I see no way to inherit from such a base class, regardless of
the base class design!
Instead of having a static method which returns a Document, create an
*instance* method which loads data into an existing instance. That's
the way XmlDocumentLoad works, for example.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 27 '07 #29
What is wrong with this approach?

class MyDocument : Document
{
public void CopyFromDocumen t(Document Original)
{
foreach (System.Reflect ion.PropertyInf o Prop in
Original.GetTyp e().GetProperti es())
{
if (Prop.CanWrite)
{
Prop.SetValue(t his, Prop.GetValue(O riginal, null),
null);
}
}
foreach (System.Reflect ion.FieldInfo Field in
Original.GetTyp e().GetFields() )
{
Field.SetValue( this, Field.GetValue( Original));
}
}
}

Something similar can be implemented in the base class and would be
inherited by your class. There may be a performance issue with
Reflection though.
Jan 27 '07 #30

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

Similar topics

37
2830
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 use the instance of this base class (or its children class). How can I ensure the instance IS-A base class instance, since Python is a fully dynamic typing language? I searched and found several different ways to do this:
5
1665
by: Robert Spoons | last post by:
Can you look over this code, preferably try it, and comment? I believe the 'extend' function below will allow you to use full 'class inheritance' in javascript, but I would like to verify it. The extend function allows the following: 1) inheriting from multiple classes, 2) inheriting an inherited classes inheritances (awkward to say), 3) inheriting appended prototype methods and properties of inhertited classes.
19
2337
by: qazmlp | last post by:
class base { // other members public: virtual ~base() { } virtual void virtualMethod1()=0 ; virtual void virtualMethod2()=0 ; virtual void virtualMethod3()=0 ;
14
12913
by: Steve Jorgensen | last post by:
Recently, I tried and did a poor job explaining an idea I've had for handling a particular case of implementation inheritance that would be easy and obvious in a fully OOP language, but is not at all obvious in VBA which lacks inheritance. I'm trying the explanation again now. I often find cases where a limited form of inheritance would eliminate duplication my code that seems impossible to eliminate otherwise. I'm getting very...
2
1537
by: Andrew Ducker | last post by:
I'm implementing a singleton using the example at: http://www.yoda.arachsys.com/csharp/singleton.html as a basis (second example). However - I have about 20 classes I wish to make singletons - and I don't want to duplicate the code in each one. The difficulty comes in the method that returns the singleton instance. In the example it's: if (instance == null) instance = new Class1(); return instance;
6
2533
by: Pascal Polleunus | last post by:
Hi, I'm wondering if there could be problems related to inheritance in the following scenario (with PostgreSQL 7.4.1)... 1 A-table, abstract. Max 10 B-tables that inherit from A, with sometimes some more columns than A. These are also abstracts.
31
1929
by: John W. Kennedy | last post by:
I quite understand about prototypes and not having classes as such, but I happen to have a problem involving blatant is-a relationships, such that inheritance is the bloody obvious way to go. I can think of several ad-hoc ways to achieve inheritance, but is there an accepted standard idiom? -- John W. Kennedy "But now is a new thing which is very old-- that the rich make themselves richer and not poorer, which is the true Gospel, for...
2
278
by: groups | last post by:
C# is an impressive language...but it seems to have one big limitation that, from a C++ background, seems unacceptable. Here's the problem: I have a third-party Document class. (This means I can't change the Document class.) I want to extend this (inherit from Document) as MyDocument, adding new events and application-specific methods and properties.
23
4604
by: Dave Rahardja | last post by:
Since C++ is missing the "interface" concept present in Java, I've been using the following pattern to simulate its behavior: class Interface0 { public: virtual void fn0() = 0; };
0
9169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9030
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8899
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8871
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7738
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6528
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5861
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4371
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.