Why can't I inherit from DateTime?

N

Nurchi BECHED

Because System.DateTime is a sealed class which means that you
cannot extend (inherit from) it.

But why in the world would you want to extend DateTime?

In the worst case, create a class, and make a DateTime field.

Hope this helps.
Good luck.

Any ideas?



--
Regards,
Nurchi BECHED

P.S.
C makes it easy to shoot yourself in the foot;
C++ makes it harder, but when you do,
it blows away your whole leg."
--Bjarne Stroustrup
 
J

Jeff Louie

???? According to the docs DateTime is a value type, a struct and you
cannot extend a struct.

Regards,
Jeff
Because System.DateTime is a sealed class which means that you cannot
extend (inherit from) it.<
 
M

Michael S

Frank Rizzo said:
Any ideas?

Have a look at value types and reference types, called structs versus
classes in C#.
In many ways, a struct is quite an opposite of a class.

Here are some differences.

A class instance is allocated with reference on stack or heap, with the
object always on heap. A struct instance is allocated directly on stack (for
local instances in methods) or embedded in an object on heap.

A class is inheritable. A struct is implicitly sealed and always inherits
from Object. (This answers your question)

A class can be cast to itself and to any superclass of it's type. A struct
can only be boxed into Object and unboxed to it's sealed type.

A class supports polymorhpism. Structs have limited support for polymorfism
as you can override or reindtroduce methods on the Object class. However,
the abstract or virtual keyword makes non sense on value types and are so
forbidden in C#.

A class instance is garbage collected. A struct instance on stack is simply
removed when a method ends or are implictly collected from heap when when an
class instance is garbage collected.

A class is a beautiful thing. structs sucks! =)

Hope this helps

- Michael S
 
R

Richard Blewett [DevelopMentor]

You forgot one - and this is the reason for their existance - With no boxing, structs are faster and smaller which is why all the primatives are valuetypes and things like System.Drawing.Point

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Frank Rizzo said:
Any ideas?

Have a look at value types and reference types, called structs versus
classes in C#.
In many ways, a struct is quite an opposite of a class.

Here are some differences.

A class instance is allocated with reference on stack or heap, with the
object always on heap. A struct instance is allocated directly on stack (for
local instances in methods) or embedded in an object on heap.

A class is inheritable. A struct is implicitly sealed and always inherits
from Object. (This answers your question)

A class can be cast to itself and to any superclass of it's type. A struct
can only be boxed into Object and unboxed to it's sealed type.

A class supports polymorhpism. Structs have limited support for polymorfism
as you can override or reindtroduce methods on the Object class. However,
the abstract or virtual keyword makes non sense on value types and are so
forbidden in C#.

A class instance is garbage collected. A struct instance on stack is simply
removed when a method ends or are implictly collected from heap when when an
class instance is garbage collected.

A class is a beautiful thing. structs sucks! =)

Hope this helps

- Michael S
 
J

Joanna Carter \(TeamB\)

You forgot one - and this is the reason for their existance - With no
boxing, structs are faster and smaller which is why all the primatives are
valuetypes and things like System.Drawing.Point

So, if I design my own value types that include events, etc and have
implicit conversion operators to simplify code e.g. IntegerType, StringType,
FloatType, etc; Am I better using structs or classes ?

If I rely on implicit operators, does remove some of the requirement for
boxing ?

Joanna
 
M

Michael S

Joanna Carter (TeamB) said:
"Richard Blewett [DevelopMentor]" <[email protected]> a écrit
dans
le message de news: #[email protected]...
You forgot one - and this is the reason for their existance - With no
boxing, structs are faster and smaller which is why all the primatives are
valuetypes and things like System.Drawing.Point

Indeed Richard and Joanna.

I added that last tidbit that structs sucks just for letting someone make
this point (about Points *S*).
However, I think there is seldom reason for defining your own value types.
Every time I start by thinking of a type as a struct I usually wind up
making it a class. I typically ask my self, - Can I assure that an instance
of this type won't be passed to a method as an Object. Most structs seldom
pass that test.

I think structs will be more used in .NET 2.0 as generic types as List<T>
and such will cope with the boxing problem. When this happens I think people
will use structs for business entities and data entities, and not interfaces
as Java typically does things.

I'd rather see a Customer as a struct and not an class or interface. The
struct says - "I am a customer and I do this and that and I am written in
stone so you can always expect the same behavour from me!" I think this
makes more sense than having an class go: - "I am perhaps a customer or
something more special than that and I may do what you expect if not
something completly overriden." Interfaces though are worst in my view: - "I
am sorta like a customer and I behave in a customerlike way. But exactly
what I do is hidden from you and may change at anytime depending on the
factory that (perhaps) loaded me dynamically. You'll never know!"

In of .NET 1.1, I don't use structs for the above purposes as it's
performance problem in regards to boxing is quite costly.

As I have always admired your articles and posts in the delphi OO group,
Johanna; I hope you comment on the above.

- Michael S
 
R

Richard Blewett [DevelopMentor]

The boxing will only occur if you pass the value to a method that takes System.Object, if you take an interface based reference or you call one of the System.Object virtual methods that you haven't overridden.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

You forgot one - and this is the reason for their existance - With no
boxing, structs are faster and smaller which is why all the primatives are
valuetypes and things like System.Drawing.Point

So, if I design my own value types that include events, etc and have
implicit conversion operators to simplify code e.g. IntegerType, StringType,
FloatType, etc; Am I better using structs or classes ?

If I rely on implicit operators, does remove some of the requirement for
boxing ?

Joanna
 
R

RichGK

Richard Blewett said:
You forgot one - and this is the reason for their existance - With no
boxing, structs are faster and smaller which is why all the primatives are
valuetypes and things like System.Drawing.Point
Regards

Richard Blewett - DevelopMentor

So why make DateTime a struct? Its not what I'd consider a primitive.
 
M

Michael S

Richard Blewett said:
The boxing will only occur if you pass the value to a method that takes
System.Object, if you take an interface based reference or you call one of
the System.Object virtual methods that you haven't overridden.

Regards

That 'only' is not as harmless as it seems. Heavily used classes as
ArrayList and HashTable is really hurt by boxing value types. When those
general classes becomes generic classes in .NET 2.0 this problem will be no
more.

In .NET 1.1 I use structs on large classes with many members to group
members in a ordely fashion. So for me structs are just for readability,
while it may become quite useful in NET 2.0.

- Michael S
 
M

Michael S

RichGK said:
boxing, structs are faster and smaller which is why all the primatives are
valuetypes and things like System.Drawing.Point

So why make DateTime a struct? Its not what I'd consider a primitive.

I think it is very much a primitive. The rules for Dates and Time is quite
clear and there is no need for polymorphism. People who use the DateTime
struct will know exactly how it behaves and nobody can change it's behavour.

It would be not so cool if you could subclass a DateTime and make that count
with Marsion dates and time. Other classes that depends on Tellus date and
time would be mighty confused. The great thing about structs is that you can
rely on them to behave exactly the same. Not in an assembly, not in a
solution, but over the whole platform (.NET).

The problem with .NET 1.1 is the boxing/unboxing performance hit.

- Michael S
 
J

Joanna Carter \(TeamB\)

I think structs will be more used in .NET 2.0 as generic types as List<T>
and such will cope with the boxing problem. When this happens I think people
will use structs for business entities and data entities, and not interfaces
as Java typically does things.

I am indeed looking to .NET 2.0 for the work I am doing and am hoping that
generics will greatly simplify the code I have to write.

My thoughts, at the moment, are to have my own 'observable' value types
possibly created from a generic value type :

struct ValueType<T>
{
// events to notify of changes, etc

// implicit operators to/from T
...
}

The theory is that a generic type would be sealed anyway, so why not use a
struct ? There should only be boxing if passed to an object parameter.
I'd rather see a Customer as a struct and not an class or interface. The
struct says - "I am a customer and I do this and that and I am written in
stone so you can always expect the same behavour from me!" I think this
makes more sense than having an class go: - "I am perhaps a customer or
something more special than that and I may do what you expect if not
something completly overriden.

But you could achieve the same end by marking a class as sealed. This then
also avoids the boxing overhead.
" Interfaces though are worst in my view: - "I
am sorta like a customer and I behave in a customerlike way. But exactly
what I do is hidden from you and may change at anytime depending on the
factory that (perhaps) loaded me dynamically. You'll never know!"

That is a poor definition of an interface :)

In that sense interfaces are contracts and are similar to pure abstract
classes. Such interfaces allow us to write program logic once and once only,
whilst allowing us to change, not what a class does, but how it does it.

Interfaces are not for deriving from, they are for implementing. Neither are
they a poor man's multiple inheritance.

Interfaces are definitions of behaviour and a class may exhibit more than
one behaviour.

The biggest misuse of interfaces is to make them too large; most good
interfaces are fairly small and concise. e.g. ICloneable, Enumerable,
IEnumerator, etc are good examples of interfaces.
In of .NET 1.1, I don't use structs for the above purposes as it's
performance problem in regards to boxing is quite costly.

I use classes/interfaces for business objects as the need to pass them as
objects is more common than for the value types held in the objects.

Joanna
 
R

RichGK

Michael S said:
I think it is very much a primitive. The rules for Dates and Time is quite
clear and there is no need for polymorphism. People who use the DateTime
struct will know exactly how it behaves and nobody can change it's behavour.

It would be not so cool if you could subclass a DateTime and make that count
with Marsion dates and time. Other classes that depends on Tellus date and
time would be mighty confused. The great thing about structs is that you can
rely on them to behave exactly the same. Not in an assembly, not in a
solution, but over the whole platform (.NET).

The problem with .NET 1.1 is the boxing/unboxing performance hit.

I totally agree with you as it could create a right mess. However, DateTime
instances respond to methods and are a primitive, this doesn't make OO sense
to me.

I'm not arguing here mind, just trying to understand why its this way in C#

Rich.
 
R

Richard Blewett [DevelopMentor]

Actually there is still a copying issue in some situations even with generics. Ian Griffiths blogged about this a short while ago

http://www.interact-sw.co.uk/iangblog/2005/01/27/modifyinsitu

And yes, I agree that structs are only useful in a small number of scenarios, ref types are the general bread and butter of .NET development. But in those scenarios where they are appropriate they can be a big win in terms of memory efficiency and performance.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk


Richard Blewett said:
The boxing will only occur if you pass the value to a method that takes
System.Object, if you take an interface based reference or you call one of
the System.Object virtual methods that you haven't overridden.

Regards

That 'only' is not as harmless as it seems. Heavily used classes as
ArrayList and HashTable is really hurt by boxing value types. When those
general classes becomes generic classes in .NET 2.0 this problem will be no
more.

In .NET 1.1 I use structs on large classes with many members to group
members in a ordely fashion. So for me structs are just for readability,
while it may become quite useful in NET 2.0.

- Michael S
 
J

Jay B. Harlow [MVP - Outlook]

Michael,
A class is inheritable. A struct is implicitly sealed and always inherits
from Object. (This answers your question)
A struct inherits from System.ValueType (which inherits from Object).
A class can be cast to itself and to any superclass of it's type. A struct
can only be boxed into Object and unboxed to it's sealed type.
A struct can be boxed into a System.ValueType variable in addition to an
Object variable. (in both cases its an Object on the heap).
A class is a beautiful thing. structs sucks! =)
Where structs are needed (such as System.Int32) they are a beautiful thing &
classes sucks!! :)

Hope this helps
Jay
 
M

Michael S

Jay B. Harlow said:
Where structs are needed (such as System.Int32) they are a beautiful thing
& classes sucks!! :)

Indeed Jay.

But .NET allready serves us with the structs we need, like Int32 and Point.

The great part with .NET and especially C# is that it does not settle with -
"It's a primitive, they are special", as in Java; but actually can describe
a Intel 32-bit register as a ValueType with methods and operators. This is
why I love C# so much that I have (almost) given up on Delphi.

It's all for show though.

ValueTypes in the System namespace is part of the Common Type System (CTS)
as per defined by the ECMA- and ISO-standards and hence the jitter (JITC)
can optimize them. Trust me; an System.Int32 is NOT a ValueType. Once
running, it's a 32-bit in register or on a stack. When you add two Int32 no
overloaded method is actually called. An actual DateTime instance is a
double on the Intel FPU stack.

The problem starts when you write your own structs. And give them overloaded
operators. And use them. And start to box and unbox them. That really hurts
in .NET 1.1.

During the day I was thinking of how structs actually could be used. And I
imagined a scenario where I needed to to do some M-Theory geometry; hence we
need several coordinates in an 11-dimensional space. As far as I know, there
is no such type in the FCL. =) A struct holding the 11 dimensions and a
class that holds the several 'points' would be an ideal case for when
structs can help classes create huge objects that is not manhandled by the
garbage collector and/or makes the L2-cache being hurt to much.

But there is seldom I need such objects, so most of the structs I plan,
winds up as classes.

Regards

- Michael S
 
J

Jay B. Harlow [MVP - Outlook]

Michael,
But .NET allready serves us with the structs we need, like Int32 and
Point.
There are numerous structs that we "need" that the framework does not
include.

Some I can thing of include, but are not limited to: Range
(http://martinfowler.com/ap2/range.html), Limit (as in insurance limits),
Complex, Money aka Quantity (http://martinfowler.com/ap2/quantity.html),
Point3d

Basically any type that:
- act like primitive types
- have an instance size under 16 bytes
- are immutable
- value semantics are desired

http://msdn.microsoft.com/library/d...genref/html/cpconValueTypeUsageGuidelines.asp

I normally strive to ensure all 4 are met when I am define a type as a
Structure. Of course there are exceptions. In fact VB.NET tries to ensure
the immutability of Value Types by calling
System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue to ensure that
a copy of the boxed structure is returned. VB.NET does not call this
function for ValueType variables, allowing you to use reflection on boxed
value types... C# does not have this "feature".
Trust me; an System.Int32 is NOT a ValueType.
Are you certain?

System.ValueType class provides the base class for value types.
http://msdn.microsoft.com/library/d...cpref/html/frlrfSystemValueTypeClassTopic.asp


In other words all value types (aka Structures) inherit from
System.ValueType, System.Int32 is a value type. Ergo *IS* a
System.ValueType!

http://msdn.microsoft.com/library/d...-us/cpref/html/frlrfSystemInt32ClassTopic.asp

Yes Int32 is special in that it maps to an actual machine type (a primitive
type), that does not preclude it from being a ValueType!

If Int32 does not Derive from System.ValueType why does the following
succeed? :)

int i = 100;
ValueType vt = i;
Object o = vt;

Why does this return True? :)

Debug.WriteLine(o is ValueType, "o is ValueType");

An actual DateTime instance is a double on the Intel FPU stack.
Are you certain? DateTime is Implemented as a (long) Integer that is the
number of ticks (100-nanosecond unit) from 12:00 midnight, January 1, 1 A.D.
(C.E.) in the GregorianCalendar. Why involve the FPU? You're not thinking of
how a COM DateTime was implemented as a Double are you?

http://msdn.microsoft.com/library/d.../cpref/html/frlrfsystemdatetimeclasstopic.asp


Hope this helps
Jay
 
M

Michael S

Jay B. Harlow said:
(C.E.) in the GregorianCalendar. Why involve the FPU? You're not thinking
of how a COM DateTime was implemented as a Double are you?

Great post Jay.

Yes, I might have assumed too much. I was thinking on how Borland
implemented time. My bad.

But I think my argument still holds (you got a headshot but no frag).

My point is:

- ValueTypes in the system namespace can freely be optimized by the jitter,
but all other ValueTypes will be compiled as written. For most applications;
the boxing/unboxing is a problem that will soon have it's remedy with
generics.

And I think we both can agree on that.

- Michael S
 
J

Jay B. Harlow [MVP - Outlook]

Michael,
- ValueTypes in the system namespace can freely be optimized by the
jitter, but all other ValueTypes will be compiled as written.
??

The JITTER is free to optimize all value types equally whether they are in
the system namespace or not.

I don't consider the fact that Int32 is a "primitive" as being "optimized"
or not.

Remember that Decimal is a value type in the System namespace, however it is
not a primitive type. I don't believe DateTime & TimeSpan are primitive
types either.

My understanding is it depends on how the value type is written (sans the
"primitive" value types) as to how much optimization they will get or not
get.
For most applications; the boxing/unboxing is a problem that will soon
have it's remedy with generics.
Naturally!

Hope this helps
Jay
 
J

Jon Skeet [C# MVP]

Michael S said:
Indeed Jay.

But .NET allready serves us with the structs we need, like Int32 and Point.

The great part with .NET and especially C# is that it does not settle with -
"It's a primitive, they are special", as in Java; but actually can describe
a Intel 32-bit register as a ValueType with methods and operators. This is
why I love C# so much that I have (almost) given up on Delphi.

It's all for show though.

ValueTypes in the System namespace is part of the Common Type System (CTS)
as per defined by the ECMA- and ISO-standards and hence the jitter (JITC)
can optimize them. Trust me; an System.Int32 is NOT a ValueType. Once
running, it's a 32-bit in register or on a stack.

Only if it's in a local variable. I fail to see how an Int32 which is
part of an instance on the heap can stick around as a register or on
the stack.

I also fail to see in what way the JIT optimisation stops it from being
a value type. What value type semantics does Int32 *not* exhibit?
When you add two Int32 no overloaded method is actually called.

That's true even at the IL level though, in this case. The DateTime
case is a bit more interesting.
An actual DateTime instance is a double on the Intel FPU stack.

If it's on the stack in the first place...
 

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