Re: C# inheritance broken?
On Jan 26, 9:06 am, gro...@isaacsof t.com wrote:
Now, I'll state first off that I'm not a C++ guru. I used it briefly.
That said, I'm having trouble imagining how this would work in any
language. Let me modify your example a bit:
class MyDocument : public Document
{
private int additionalFIeld = 15;
public static MyDocument Load(string FileName)
{
return (MyDocument)Doc ument.Load(File Name);
}
}
So... you're telling me that C++ somehow, magically, knows that when
MyDocument.Load calls Document.Load it must allocate additional space
for the object for the fields that are a part of MyDocument but not
part of Document? How could it possibly know?
OR
Are you saying that in C++ you can cheat and cast a base type to a
derived type and get away with it so long as the derived type has no
additional fields? (And so, by inference, if the derived type _does_
have additional fields then the cast still works but all hell breaks
loose at runtime?)
If you're suggesting the latter, then from a .NET point of view it is
C++ that is "broken". .NET was explicitly designed to _not_ allow
programmers to play fast and loose with objects. The whole idea is to
_guarantee_ that casts are valid, and that pointers point to the right
thing, so as to mitigate all sorts of hacking attacks that depend upon
overlaying memory that contains one thing with a definition for a
different thing and then having a field day with arbitrary operations
in memory.
For example, the following is perfectly legal C:
char x[4];
int *p = (int *)&x;
int y = *p;
Memory is plastic in C/C++: you can flip between types and the compiler
assumes that you know what you're doing. In C#, the compiler assumes
nothing. The compiler / CLR combine to make solid guarantees about what
is what and what operations you're allowed to perform. As such, if you
want to stick to what's called "safe" code in C#, you can't play these
sorts of tricks. The compiler / runtime won't let you. There's nothing
broken about it: just different design goals.
On Jan 26, 9:06 am, gro...@isaacsof t.com wrote:
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#.
>
<snip>
>
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);
}
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#.
>
<snip>
>
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);
}
That said, I'm having trouble imagining how this would work in any
language. Let me modify your example a bit:
class MyDocument : public Document
{
private int additionalFIeld = 15;
public static MyDocument Load(string FileName)
{
return (MyDocument)Doc ument.Load(File Name);
}
}
So... you're telling me that C++ somehow, magically, knows that when
MyDocument.Load calls Document.Load it must allocate additional space
for the object for the fields that are a part of MyDocument but not
part of Document? How could it possibly know?
OR
Are you saying that in C++ you can cheat and cast a base type to a
derived type and get away with it so long as the derived type has no
additional fields? (And so, by inference, if the derived type _does_
have additional fields then the cast still works but all hell breaks
loose at runtime?)
If you're suggesting the latter, then from a .NET point of view it is
C++ that is "broken". .NET was explicitly designed to _not_ allow
programmers to play fast and loose with objects. The whole idea is to
_guarantee_ that casts are valid, and that pointers point to the right
thing, so as to mitigate all sorts of hacking attacks that depend upon
overlaying memory that contains one thing with a definition for a
different thing and then having a field day with arbitrary operations
in memory.
For example, the following is perfectly legal C:
char x[4];
int *p = (int *)&x;
int y = *p;
Memory is plastic in C/C++: you can flip between types and the compiler
assumes that you know what you're doing. In C#, the compiler assumes
nothing. The compiler / CLR combine to make solid guarantees about what
is what and what operations you're allowed to perform. As such, if you
want to stick to what's called "safe" code in C#, you can't play these
sorts of tricks. The compiler / runtime won't let you. There's nothing
broken about it: just different design goals.
Comment