Choosing Between Classes and Structures

  • Thread starter Thread starter Ray Cassick
  • Start date Start date
R

Ray Cassick

I have been investigating this subject a bit and ran across this gem in
MSDN:

http://msdn.microsoft.com/en-us/library/ms229017(VS.80).aspx

This seems to specifically state that structures should not be any longer
that 16 bytes in size. Seems a bit limiting to me since I can hit that limit
by this:

Public Structure MyStruct
Dim field1 as ULong
Dim field2 as ULong
Dim field3 as ULong

End Structure

I am assuming that they have a good reason for saying this but I have looked
everywhere and cant seem to locate it. Can someone comment as to why this is
the case? I am assuming is has something to do with memory allocation on the
stack versus the heap but I would love to locate a good definitive answer...

Thanks for any pointers...
 
Peter Duniho said:
Actually, it's worse than that. They say you should be _smaller_ than 16
bytes. 15 bytes is okay, 16 bytes is not. :)

I doubt that there's any specific performance threshold related to that
size. 16 bytes happens to be the size of a 32-bit Rectangle structure and
I'd guess someone just felt that's about as big a struct should get. And
then of course mis-worded the documentation in a way that suggests that
the Rectangle struct is actually too large. :)

Anyway, I would not treat the rule as an absolute. However, I would tend
to agree with it that if you find yourself making a struct much larger
than that, you may want to consider just switching to a class. Not
because of a specific performance issue, but because the size of the data
structure is somewhat correlated to the complexity, and structs really
ought to be semantically simple (as in the other suggestion on that page
that your struct should represent something that is logically just one
"thing").

Pete

Thanks for the response...

Yeah, I caught that bit about needing to be smaller than 16 Bytes too.
Chalked it up to an 'oops' in wording there.

16 bytes just seemed really small. I use structures a lot anytime I need to
pass data across functional boundaries but don't need to give it much
functionality that would require a class type structure. Like if I want to
just write out a series of records to a file I will build the record
structure, populate it and then write it out. Sometimes just writing out to
a stream using a structure is so much simpler than serializing something,
especially if I just need it written out to something simple for consumption
in another app. XML is good but you can cross the line and just induce a ton
of overhead if you are not careful.

I was just worried that by creating structures too large I may be inducing a
performance hit if there was some magic limit between being stored on the
stack vs. the heap that I was not aware of.

Thanks again.
 
Ray Cassick said:
16 bytes just seemed really small. I use structures a lot anytime I need to
pass data across functional boundaries but don't need to give it much
functionality that would require a class type structure.

The differences between classes and structs are all to do with value
type behaviour vs reference type behaviour. It's not a matter of how
much functionality something's got. DateTime has quite a lot of
functionality, but it's a natural value type. There are plenty of
reference types which are quite simple, but are more naturally
reference types.

Personally I treat class as the "default" and only very occasionally
create structs. In particular, I always avoid creating mutable structs
- they can cause very subtle issues.
 
I have been investigating this subject a bit and ran across this gem in
MSDN:

http://msdn.microsoft.com/en-us/library/ms229017(VS.80).aspx

This seems to specifically state that structures should not be any longer
that 16 bytes in size. Seems a bit limiting to me since I can hit that limit
by this:

Public Structure MyStruct
Dim field1 as ULong
Dim field2 as ULong
Dim field3 as ULong

End Structure

I am assuming that they have a good reason for saying this but I have looked
everywhere and cant seem to locate it. Can someone comment as to why this is
the case? I am assuming is has something to do with memory allocation on the
stack versus the heap but I would love to locate a good definitive answer...

I find there to be a very simple rule of thumb: if your type warrants
overloading operator== (and other comparison operators) for it, then a
struct is very likely to be a better choice. Otherwise, go for
classes.

This works because overloading operator== typically means you want
structural (value-based) equality, and that is a sign of working with
raw data rather than objects (for the later, you usually care more
about identity).

Performance considerations should be secondary to this, but matter
also. Sometimes you have a raw data object, but with a lot (say, 10+)
of aggregated fields. Semantically, it should be a value type (because
it has strictly value semantics, and identity does not matter), but
copying that much stuff around for every argument/return value becomes
expensive - that's when you go for immutable class (but it is still
best to redefine Equals and overload operator== and != to indicate
that this is really a value type in disguise).
 
Back
Top