Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why can't I inherit from DateTime?

6 views
Skip to first unread message

Frank Rizzo

unread,
Feb 22, 2005, 9:25:32 PM2/22/05
to
Any ideas?

Nurchi BECHED

unread,
Feb 22, 2005, 9:31:04 PM2/22/05
to
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.

On Tue, 22 Feb 2005 18:25:32 -0800, Frank Rizzo <no...@none.com> wrote:

> 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

Jeff Louie

unread,
Feb 22, 2005, 11:47:47 PM2/22/05
to
???? 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.<

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Michael S

unread,
Feb 23, 2005, 3:22:28 AM2/23/05
to
"Frank Rizzo" <no...@none.com> wrote in message
news:OnXu77UG...@TK2MSFTNGP12.phx.gbl...
> 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

Richard Blewett [DevelopMentor]

unread,
Feb 23, 2005, 3:34:41 AM2/23/05
to microsoft.public.dotnet.languages.csharp
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

Joanna Carter (TeamB)

unread,
Feb 23, 2005, 3:53:20 AM2/23/05
to
"Richard Blewett [DevelopMentor]" <rich...@NOSPAMdevelop.com> a écrit dans
le message de news: #ro9FKYG...@TK2MSFTNGP14.phx.gbl...

> 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

--
Joanna Carter
Consultant Software Engineer


Michael S

unread,
Feb 23, 2005, 5:02:24 AM2/23/05
to

"Joanna Carter (TeamB)" <joa...@nospamforme.com> wrote in message
news:uN3V4UYG...@TK2MSFTNGP09.phx.gbl...

> "Richard Blewett [DevelopMentor]" <rich...@NOSPAMdevelop.com> a écrit
> dans
> le message de news: #ro9FKYG...@TK2MSFTNGP14.phx.gbl...
>> 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



Richard Blewett [DevelopMentor]

unread,
Feb 23, 2005, 5:02:47 AM2/23/05
to microsoft.public.dotnet.languages.csharp
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]" <rich...@NOSPAMdevelop.com> a ?crit dans

RichGK

unread,
Feb 23, 2005, 5:17:14 AM2/23/05
to

"Richard Blewett [DevelopMentor]" <rich...@NOSPAMdevelop.com> wrote in
message news:%23ro9FKY...@TK2MSFTNGP14.phx.gbl...

> 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.


Michael S

unread,
Feb 23, 2005, 5:24:22 AM2/23/05
to

"Richard Blewett [DevelopMentor]" <rich...@NOSPAMdevelop.com> wrote in
message news:OiYlU7YG...@TK2MSFTNGP12.phx.gbl...

> 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


Michael S

unread,
Feb 23, 2005, 5:32:59 AM2/23/05
to

"RichGK" <sss...@rrr.rr> wrote in message
news:KKYSd.21443$8B3....@text.news.blueyonder.co.uk...

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


Joanna Carter (TeamB)

unread,
Feb 23, 2005, 7:20:34 AM2/23/05
to
"Michael S" <a@b.c> a écrit dans le message de news:
ONM1H7YG...@tk2msftngp13.phx.gbl...

> 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.

RichGK

unread,
Feb 23, 2005, 7:32:54 AM2/23/05
to

"Michael S" <a@b.c> wrote in message
news:ezkENMZG...@TK2MSFTNGP14.phx.gbl...

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.


Richard Blewett [DevelopMentor]

unread,
Feb 23, 2005, 7:40:15 AM2/23/05
to microsoft.public.dotnet.languages.csharp
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

Jay B. Harlow [MVP - Outlook]

unread,
Feb 23, 2005, 11:15:32 AM2/23/05
to
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

"Michael S" <a@b.c> wrote in message

news:uPrtRDYG...@TK2MSFTNGP10.phx.gbl...

Michael S

unread,
Feb 23, 2005, 1:01:21 PM2/23/05
to

"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> wrote in message
news:%23zx6wLc...@TK2MSFTNGP14.phx.gbl...

> 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


Jay B. Harlow [MVP - Outlook]

unread,
Feb 23, 2005, 1:30:25 PM2/23/05
to
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/default.asp?url=/library/en-us/cpgenref/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/default.asp?url=/library/en-us/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/default.asp?url=/library/en-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/default.asp?url=/library/en-us/cpref/html/frlrfsystemdatetimeclasstopic.asp


Hope this helps
Jay


"Michael S" <a@b.c> wrote in message

news:%23ZyQwGd...@TK2MSFTNGP09.phx.gbl...

Michael S

unread,
Feb 23, 2005, 1:52:46 PM2/23/05
to

"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> wrote in message
news:eH4oHXdG...@TK2MSFTNGP09.phx.gbl...

> (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

Jay B. Harlow [MVP - Outlook]

unread,
Feb 23, 2005, 2:16:12 PM2/23/05
to
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

"Michael S" <a@b.c> wrote in message

news:%23jrlejd...@TK2MSFTNGP09.phx.gbl...

Jon Skeet [C# MVP]

unread,
Feb 23, 2005, 2:20:04 PM2/23/05
to
Michael S <a@b.c> wrote:
> 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...

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jon Skeet [C# MVP]

unread,
Feb 23, 2005, 2:22:25 PM2/23/05
to
Michael S <a@b.c> wrote:

<snip>

> My point is:
>
> - ValueTypes in the system namespace can freely be optimized by the
> jitter, but all other ValueTypes will be compiled as written.

No - the JIT can still optimise freely within the normal boundaries.
While it may have more knowledge about certain value types, there's
nothing to stop it from still optimising user-defined value types
heavily too, inlining operations etc.

> 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.

That I agree with - for the most part. (Generics won't *always* prevent
boxing and unboxing. They're not a silver bullet. They'll help a great
deal though.)

Jay B. Harlow [MVP - Outlook]

unread,
Feb 23, 2005, 2:23:29 PM2/23/05
to
Doh!

> 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.
I should add that "primitive" value types actually use different IL opcodes,
so although the JIT will optimize them, the optimizations is going to be
different then non primitive value types...

Hope this helps
Jay

"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> wrote in message

news:urt1kwdG...@tk2msftngp13.phx.gbl...

Bruce Wood

unread,
Feb 23, 2005, 2:42:39 PM2/23/05
to
Sorry, but I roundly disagree with you about making something like
Customer a struct (and thus a value type). This is exactly the kind of
thing that gets ex-C programmers (like me) in no end of trouble:
confusing C "structs" with C#'s value types. They are not the same. Too
many ex-C hacks continue to think that "struct" in C# should signal
some sort of "class lite", the way it does in other languages. It
absolutely doesn't. Trust me: I tried it. It sucked. Creating a

public struct Customer

is an absolutely horrible idea in C#. That's not what C# structs are
for.

At a conceptual level, C# structs are intended for those cases in which
you want _value semantics_ rather than _reference semantics_. The most
common situation is one in which you want to introduce a new type that
acts like primitive types: is immutable, is involved in calculations,
is passed by value rather than by reference, etc.

There are myriad situations in which this is a useful thing to be able
to do. C# certainly does _not_ "already give us all of the value types
we'll ever need." Not at all. For example, I work in the lumber
industry. We need fractional measures. My software needs to store 3
1/2, 11/16, and values like that. I need to be able to math with them,
reduce them, normalize them... all the stuff you need to do with
fractions. If I created a Fraction class, it would suck. I don't want
to be able to keep a reference to a Fraction and modify it. I want it
to act like an int or a double, so C# structs to the rescue! Of course,
you can do other things with structs, and they don't _have_ to be
immutable, but mutable structs are rare birds indeed, and so are more
likely than not a misuse of C#.

True, in C# you want a class 99% of the time, but structs are very
handy to have in those other 1% of cases. Structs only "suck" when you
try to use them for that for which they weren't intended. A screwdriver
makes a lousy hammer, which _doesn't_ mean that it "sucks" as a
screwdriver. Neither does it stop people from _trying_ to use it as a
hammer. :-)

Michael S

unread,
Feb 23, 2005, 2:41:46 PM2/23/05
to

"Jay B. Harlow [MVP - Outlook]" <Jay_Har...@msn.com> wrote in message
news:urt1kwdG...@tk2msftngp13.phx.gbl...

> 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.

- But it can't.

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

- I don't either. I used the word primitive as an comparison to Java.
System.Int32 is indeed a ValueType in CIL, but not native. And that is
important.


> 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.

- There is no such thing as a primitive type in C#, just value types. This
is true for CIL. But there are a few types that will get special treatment
by the native JIT-compiler. Which is true not only for structs, but classes
too. String are one class I'm thinking of.

>> For most applications; the boxing/unboxing is a problem that will soon
>> have it's remedy with generics.
> Naturally!
>
> Hope this helps

- It did. Thanks! =)

> Jay

- Michael S


Michael S

unread,
Feb 23, 2005, 2:59:52 PM2/23/05
to

"Jon Skeet [C# MVP]" <sk...@pobox.com> wrote in message
news:MPG.1c86e7bf7...@msnews.microsoft.com...

> Michael S <a@b.c> wrote:
>> 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.

- Hehe Jon, I fail to see how you can do anything with an integer if you
don't get it into a cpu-register sooner or later. while a loop is running,
integers tend to stay in a register or in the cache. =)

>
> 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?

- That's my point. .Net and C# actually manage to get a cpu-register to come
out in C# as a dandy ValueType. It's brilliant!

However, if the jitter didn't optimize some ValueTypes, .NET would have the
blazing speed resembling a C-64. =)

>
>> 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...

- Well as I was wrong about what a DateTime is, I'm not sure I should get
more involved. =)

My best regards Jon

- Michael

Jon Skeet [C# MVP]

unread,
Feb 23, 2005, 3:08:15 PM2/23/05
to
Michael S <a@b.c> wrote:
> >> 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.
>
> - Hehe Jon, I fail to see how you can do anything with an integer if you
> don't get it into a cpu-register sooner or later. while a loop is running,
> integers tend to stay in a register or in the cache. =)

You can easily end up with integers which are *copied* into registers
or copied onto the stack though - or even just copied from one location
on the heap to another. The point is that your statement implied that
ints were *always* on the stack or in registers, which they're clearly
not.

> > 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?
>
> - That's my point. .Net and C# actually manage to get a cpu-register to come
> out in C# as a dandy ValueType. It's brilliant!

Agreed - but it goes against what you were saying before about it not
being a value type.

> However, if the jitter didn't optimize some ValueTypes, .NET would have the
> blazing speed resembling a C-64. =)

Of course.

<snip>

Jon Skeet [C# MVP]

unread,
Feb 23, 2005, 3:13:06 PM2/23/05
to
Michael S <a@b.c> wrote:
> > The JITTER is free to optimize all value types equally whether they are in
> > the system namespace or not.
>
> - But it can't.
>
> > I don't consider the fact that Int32 is a "primitive" as being "optimized"
> > or not.
>
> - I don't either. I used the word primitive as an comparison to Java.
> System.Int32 is indeed a ValueType in CIL, but not native. And that is
> important.

It's a primitive type which has specific CIL instructions for it.
That's pre-JIT special handling.

> > 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.
>
> - There is no such thing as a primitive type in C#, just value types. This
> is true for CIL.

No it's not. Look at Type.IsPrimitive. Ints not only get special
treatment by the JIT, they get special treatment by the C# compiler.

Compile the following, and then look at it in ildasm:

using System;

public class Test
{
static void Main()
{
int i = 5;
int j = 10;
int k = i+j;

decimal d = 1m;
decimal e = 2m;
decimal f = d+e;
}
}

The code for both the creation and addition is radically different for
int and decimal.

Michael S

unread,
Feb 23, 2005, 3:45:46 PM2/23/05
to

I stand corrected and you have a point.
Structs should be for invariant and mutable things only.

A customer should not be 'copied by value', it is one costomer, and hence
one instance.. ..of a class.

Great post Bruce

- Michael S

"Bruce Wood" <bruc...@canada.com> wrote in message
news:1109187759.6...@o13g2000cwo.googlegroups.com...

Jay B. Harlow [MVP - Outlook]

unread,
Feb 23, 2005, 3:52:33 PM2/23/05
to
Michael,

>> The JITTER is free to optimize all value types equally whether they are
>> in the system namespace or not.
> - But it can't.
Why not?

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

It appears you are as you are considering Int32 to be "optimized", when its
really "primitive". I don't consider the special treatment of Int32 to be
"optimized".

> - There is no such thing as a primitive type in C#, just value types. This

As Jon stated, yes there are. Int32 is one of them. The primitive types are
those types that have specific IL representation/support (IL opcodes), such
as Integers & Doubles. Value types such as DateTime & Decimal are not
primitive.

Look at the IL of the sample that Jon posted, notice how the "int" IL code
is different then the "Decimal" IL code. I don't consider this an
optimization as much as its simply the difference of how code for primitive
types differ from code for non-primitive types. At a higher abstract level,
yes the IL code can be considered optimized, however the C# compiler did
this, not the jitter!

Hope this helps
Jay

"Michael S" <a@b.c> wrote in message

news:OWZC3%23dGF...@TK2MSFTNGP10.phx.gbl...

Michael S

unread,
Feb 23, 2005, 4:11:38 PM2/23/05
to

"Joanna Carter (TeamB)" <joa...@nospamforme.com> wrote in message
news:u5lJvIaG...@TK2MSFTNGP15.phx.gbl...

> "Michael S" <a@b.c> a écrit dans le message de news:
> ONM1H7YG...@tk2msftngp13.phx.gbl...

> 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 code could be simplified this minute if I was allowed to do it, but my
shop have a policy of 'not releasing anything built on beta'. Hence I get to
wait. Poor me...


> But you could achieve the same end by marking a class as sealed. This then
> also avoids the boxing overhead.

Indeed.


> That is a poor definition of an interface :-)

---
* huge snip*
---

On purpose. And that's my whole issue with interfaces. They are often used
wrong.

Surely, the one great example on how interfaces are great is how XML is
handled on most platforms. I think it is excellent that an node in every
xml-stack is an interface. As it implies it is like a node. And will serve
like a node no matter the implementation.

Do you remember using COM in Delphi? It's painstaking but the best I've seen
so far. And it still ok as the the interface is there to suply for a
language-driven factory. Excellent.

And all interfaces should be 'like' someting. And I think people use
interfaces wrong often.

In your own example that I snipped, you mentioned IClonable and IDisposable.
But sometimes I stumble into to ICustomer and even IOrder. Now that is plain
bad use of interfaces. And it fails my test. Whenever do you need a
ICustomerlike object and what does an IOrderable object do? Get my point?


> 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

- Michael S


Michael S

unread,
Feb 23, 2005, 4:29:27 PM2/23/05
to
I learn more and more.

Thanks Jay and Jon! It pays to provoce you guys... =)

- Michael S


Jay B. Harlow [MVP - Outlook]

unread,
Feb 24, 2005, 10:13:01 AM2/24/05
to
Joanna,

> But you could achieve the same end by marking a class as sealed. This then
> also avoids the boxing overhead.

Sealing a Class has *no* effect on any boxing overhead! As only value types
are ever boxed!

Classes are reference types, Structures are value types.

>> 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.

Sealing the class prevents others from inheriting from it. Which what
Michael wants to prevent others doing to Customer.

Hope this helps
Jay


"Joanna Carter (TeamB)" <joa...@nospamforme.com> wrote in message

news:u5lJvIaG...@TK2MSFTNGP15.phx.gbl...

Jeffrey Palermo, MCAD.Net

unread,
Feb 25, 2005, 11:27:19 AM2/25/05
to
I'd like to help sum up this thread by putting out the _general_ rule
that when thinking about whether to implement a struct or class, if the
type is going to have only value type members, it's a candidate for a
struct, but if any of the members are going to be a reference type, it
should be implemented as a class.

For example, since my Customer object will need a String for the name
field, it must be a class.

If we look at the DateTime object, the only fields it contains are
value types.

I'd like to hear if anyone on this thread disagrees with this general
rule (aimed as people who don't intimitely understand stack/heap, etc).

Best regards,
Jeffrey Palermo
Blog: http://www.jeffreypalermo.com

Jon Skeet [C# MVP]

unread,
Feb 25, 2005, 12:42:28 PM2/25/05
to
Jeffrey Palermo, MCAD.Net <jeffrey...@gmail.com> wrote:
> I'd like to help sum up this thread by putting out the _general_ rule
> that when thinking about whether to implement a struct or class, if the
> type is going to have only value type members, it's a candidate for a
> struct, but if any of the members are going to be a reference type, it
> should be implemented as a class.

I'm not sure I agree with that. In fact, I definitely don't, with a
counterexample.

See http://www.pobox.com/~skeet/csharp/threads/alternative.shtml for
the general background, and
http://www.pobox.com/~skeet/csharp/miscutil for the source - LockToken
is a struct which has a field of type Object. It absolutely should be a
struct, and it absolutely needs that field.

Bruce Wood

unread,
Feb 25, 2005, 12:50:21 PM2/25/05
to
I disagree with this general rule. Whether something should be a struct
or a class does touch on whether it contains value or reference
members, however this is just one aspect of the decision, and not even
the most important one. I have a value type that contains a reference
member, and it should be a value type!

For newbies who are just starting out with C#, my general rule is
simple: you want a class. Period. Don't use structs unless you know you
need a struct.

How do you know you need a struct? You need a struct when you need
_value semantics_. There are lots of other hints that you might need a
struct, or hints that maybe that struct you built should be a class,
but that's the biggie: do you want value semantics? Do you want the
thing to act like an int or a double: be copied on every assignment, be
copied when being passed to a method, etc? Does it represent some sort
of quantity, or value, rather than a "thing" in the sense that a
Customer is a "thing" that deserves an identity whereas an integer is a
value.

Here's a big hint: could you give it a unique key? Would that make
sense? Customers have customer numbers; sales orders have sales order
numbers. These are all classes, pure and simple. An integer doesn't
have a UID, and couldn't have a UID. The concept makes no sense. That
means that it _might_ make a good value type (in the case of integer,
of course, it does).

As I said, I have a value type that contains a reference member: it's
called Measure, and it's a Decimal coupled with a unit of measure,
which is a class (reference type) in my system. Measure, however, is
clearly a value: I do mathematical operations with it. I want it to be
copied when it's assigned. I want it to be immutable: I certainly don't
want to have a reference to a Measure and go modifying it. I want it to
have _value semantics_.

On the other hand, I can imagine a class such as "annual sales figures"
that contains nothing more than values: a customer number, a start
date, and buckets for monetary values. No reference types. However, it
is a "thing," insofar as it is conceivable (and probable) that it has
UID (the customer number plus the start date). As well, you may want to
modify the sales figures for a customer for a time period. Definitely
reference semantics stuff. Definitely a class.

So, no: whether something contains only value types is not a good way
of deciding whether it needs to be a struct.

Jay B. Harlow [MVP - Outlook]

unread,
Feb 25, 2005, 3:22:54 PM2/25/05
to
Jeffrey,
I too disagree with this rule!

I agree with Bruce & Jon, use a Class unless you really need to use a
Struct.

When do you need to use a Struct?

I follow the .NET Design Guidelines, in that you need a Struct when your
type needs to:


- act like primitive types
- have an instance size under 16 bytes
- are immutable
- value semantics are desired

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconValueTypeUsageGuidelines.asp

The more of the above 4 items your Type needs, the more likely it needs to
be a Struct.

Hope this helps
Jay

"Jeffrey Palermo, MCAD.Net" <jeffrey...@gmail.com> wrote in message
news:1109348839.2...@z14g2000cwz.googlegroups.com...

Jeffrey Palermo, MCAD.Net

unread,
Feb 26, 2005, 5:55:21 PM2/26/05
to
Wow, great feedback. After this discussion and reading the content in
the links provided, I must take back my previous post. Yes, value
semantics must weigh out in the decision process. I _do_ like the
general rule: "Use a class" for those wondering which one to use.
Personally, I have never had the need for a struct. I do mostly
business applications where my object have an identify.

I'd like to ask a question about the 2nd MS guideline: "have an
instance size under 16 bytes". Is that really a hard and fast rule?
The DateTime struct, if you look at all the "long" members, its
instance size would be more than 16 bytes.

Bruce Wood

unread,
Feb 26, 2005, 6:33:18 PM2/26/05
to
No, I think that the "less than 16 bytes" rule is more a guideline. It
simply asks you to keep in mind that value types are copied whenever
they are assigned, and if you create a large value type then all of
that copying will have a performance penalty.

However, it really depends upon how often you use the type in question,
and what else your application is doing. If your app spends all of its
time in the CPU, and the type in question is heavily used, then big
value types could be a problem.

If you're writing an application that reads from a database (and so you
spend most of your user's "real time" waiting for the database to
answer you), and the value type is not often used, then it probably
doesn't matter how big it is.

Jeffrey Palermo, MCAD.Net

unread,
Feb 26, 2005, 9:58:26 PM2/26/05
to
Thanks, Bruce. This thread has turned out to be a great discussion.

Jon Skeet [C# MVP]

unread,
Feb 27, 2005, 2:29:45 AM2/27/05
to
Jeffrey Palermo, MCAD.Net <jeffrey...@gmail.com> wrote:

<snip>

> I'd like to ask a question about the 2nd MS guideline: "have an
> instance size under 16 bytes". Is that really a hard and fast rule?
> The DateTime struct, if you look at all the "long" members, its
> instance size would be more than 16 bytes.

Which members are those? I think there's really just one.

Cor Ligthert

unread,
Feb 27, 2005, 4:24:43 AM2/27/05
to
Bruce,

In my opinion the best message in this thread.

Compliments

:-)

Cor


Jay B. Harlow [MVP - Outlook]

unread,
Feb 27, 2005, 11:50:56 AM2/27/05
to
Jeffrey,
As Bruce states the "instance size under 16 bytes" is a guide line (all four
are guidelines).

> The DateTime struct, if you look at all the "long" members, its
> instance size would be more than 16 bytes.

The size of a DateTime is a single Long. Don't confuse the size of various
properties with the underlying storage. The only real value stored is
DateTime.Ticks, the other properties are derived from DateTime.Ticks.

<quote>
Note Prior to the .NET Framework 2.0, a DateTime consisted solely of a ticks
field, which is a 62-bit unsigned field that contains the number of ticks
that represent the date and time. The value of the ticks field can be
obtained with the Ticks property.
</quote>

http://msdn2.microsoft.com/library/03ybds8y.aspx

Hope this helps
Jay

"Jeffrey Palermo, MCAD.Net" <jeffrey...@gmail.com> wrote in message

news:1109458521.8...@o13g2000cwo.googlegroups.com...

Jeffrey Palermo, MCAD.Net

unread,
Feb 27, 2005, 10:40:40 PM2/27/05
to
Jon,
You are right. It only has one instance field, a long. I didn't look
closely enough. All the others are static or constants.

I did find System.Diagnostics.CounterSample that has 7 long members (8
bytes per field). Am I right about that?

So this may be one time where the 16 bytes is exceeded, but I can see
the reason to keep the instance size as small as possible.

Jon Skeet [C# MVP]

unread,
Feb 28, 2005, 5:42:02 PM2/28/05
to
Jeffrey Palermo, MCAD.Net <jeffrey...@gmail.com> wrote:
> You are right. It only has one instance field, a long. I didn't look
> closely enough. All the others are static or constants.
>
> I did find System.Diagnostics.CounterSample that has 7 long members (8
> bytes per field). Am I right about that?

I think so.



> So this may be one time where the 16 bytes is exceeded, but I can see
> the reason to keep the instance size as small as possible.

Yup. I think the main point is to favour reference types in general.

Nurchi BECHED

unread,
Mar 7, 2005, 1:30:52 AM3/7/05
to
A simple answer to your question is:
JUST BECAUSE MICROSOFT DOESN'T WANT YOU TO DO THAT!!!

Otherwise, they would have created a class called DateTime

On Tue, 22 Feb 2005 18:25:32 -0800, Frank Rizzo <no...@none.com> wrote:

> 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

0 new messages