By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,389 Members | 2,010 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,389 IT Pros & Developers. It's quick & easy.

Naming structs with a variable

P: n/a
I am new to C# and to structs so this could be easy or just not
possible.
I have a struct defined called Branch
If I use Branch myBranch = new Branch(i); // everything works
If I use Branch (myBranch + x) = new Branch(i); // it doesn't

x is a loop iterator, i is an int for the constructor to define an
array.

What am I doing wrong here.

May 10 '06 #1
Share this Question
Share on Google+
61 Replies


P: n/a
First of all, make Branch a class, not a struct.

Second, I'm not sure exactly what you're trying to do in the second
line. If you're trying to initialize an array of Branch'es, then you
need something like this:

int branchArraySize = 20;
Branch[] branchArray = new Branch[branchArraySize];
for (int i = 0; i < branchArray.Length; i++)
{
branchArray[i] = new Branch(i);
}

The second line declares and creates an array of references that could
point to Branch'es, but the array is empty: each entry is null, so
there are no actual branches stored in it yet.

The line inside the loop creates a new Branch object for each entry in
the array and assigns the array entry to refer to that new Branch that
was just created.

Is that sort of what you wanted to do?

May 10 '06 #2

P: n/a
Thanks for the reply.
What I have is a bunch of comma delimited text files for a source. They
have many "Branches" of various lengths. I don't know how many branches
or how long each branch is because they are all different. What I am
trying to end up with is an instance of a Branch for each branch in the
file. My definition of branch contains an array (array(length,3)) that
gets set to the length of the branch. Something like this:

Branch1, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
Branch2, length
item1, item2, item3
item1, item2, item3
Branch3, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
And so on ...

When I read the start of a branch I create a branch instance. Then I
fill the array in that instance with the info for each line. So I
figured in all my infinite wisdom that I could create a new Branch
struct every time I hit the start and use my iterator to name that
struct. Hence the name (MyBranch + x). Then I could work on the data in
each randomly.
I chose to use structs because I only need to store information of each
branch and I don't need any inheritance properties of a class. But if I
need to use a class or that's better I will, it was just one of those
newbie choices I made reading a book.

May 10 '06 #3

P: n/a
"Bruce Wood" <br*******@canada.com> wrote:
First of all, make Branch a class, not a struct.


I'm curious -- why did you advise that?

--
Lucian
May 10 '06 #4

P: n/a
I'd do what Bruce suggested, except add each branch to a Hashtable. then you
can make the Key of each item correspond to your expected "Branch"
+i.ToString() nomenclature and you don't need to worry about array bounds.
I'm not sure why Bruce suggested using a class instead of a struct.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Marty" wrote:
Thanks for the reply.
What I have is a bunch of comma delimited text files for a source. They
have many "Branches" of various lengths. I don't know how many branches
or how long each branch is because they are all different. What I am
trying to end up with is an instance of a Branch for each branch in the
file. My definition of branch contains an array (array(length,3)) that
gets set to the length of the branch. Something like this:

Branch1, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
Branch2, length
item1, item2, item3
item1, item2, item3
Branch3, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
And so on ...

When I read the start of a branch I create a branch instance. Then I
fill the array in that instance with the info for each line. So I
figured in all my infinite wisdom that I could create a new Branch
struct every time I hit the start and use my iterator to name that
struct. Hence the name (MyBranch + x). Then I could work on the data in
each randomly.
I chose to use structs because I only need to store information of each
branch and I don't need any inheritance properties of a class. But if I
need to use a class or that's better I will, it was just one of those
newbie choices I made reading a book.

May 10 '06 #5

P: n/a
If the only member variable in Branch is the array, it doesn't really
matter if you use a class or a struct, as long as you don't try to
replace the array with a new array.

I would make it a class, though, and add useful things to it like an
AddItems method.

Use a list to keep track of the Branch instances. If you use framework
1.1 you would use an ArrayList (list of Object). In framework 2.0 you
can use generics to make a type safe list:

List<Branch> branches = new List<Branch>();

Now you can add branches to the list:

Branch branch = new Branch(i);
branches.Add(branch);
Marty wrote:
Thanks for the reply.
What I have is a bunch of comma delimited text files for a source. They
have many "Branches" of various lengths. I don't know how many branches
or how long each branch is because they are all different. What I am
trying to end up with is an instance of a Branch for each branch in the
file. My definition of branch contains an array (array(length,3)) that
gets set to the length of the branch. Something like this:

Branch1, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
Branch2, length
item1, item2, item3
item1, item2, item3
Branch3, length
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
item1, item2, item3
And so on ...

When I read the start of a branch I create a branch instance. Then I
fill the array in that instance with the info for each line. So I
figured in all my infinite wisdom that I could create a new Branch
struct every time I hit the start and use my iterator to name that
struct. Hence the name (MyBranch + x). Then I could work on the data in
each randomly.
I chose to use structs because I only need to store information of each
branch and I don't need any inheritance properties of a class. But if I
need to use a class or that's better I will, it was just one of those
newbie choices I made reading a book.

May 10 '06 #6

P: n/a
>>First of all, make Branch a class, not a struct.
I'm curious -- why did you advise that?


I will reply to this later. I just typed a long, detailed explanation
and then hit the Windows Start key instead of Alt, and blew it all
away. I'll retype it after I do some research on how to disable that
&*(%$ key that I've never used and always hoses me. Grrrr.....

May 10 '06 #7

P: n/a
Lucian Wischik <lu***@wischik.com> wrote:
"Bruce Wood" <br*******@canada.com> wrote:
First of all, make Branch a class, not a struct.


I'm curious -- why did you advise that?


I suspect it's because class is almost always a wise "default" to take
- creating your own custom struct is very rarely required, and value
type semantics can often cause confusion. (Admittedly reference type
semantics can also cause confusion...)

I can only remember a single struct I've written, and that was for
performance reasons (where it was actually justified, just for a
change).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 10 '06 #8

P: n/a
OK... let's try this again.
First of all, make Branch a class, not a struct.
I'm curious -- why did you advise that?


For two reasons.

First, remember that structs are value types in .NET. That means that,
like an int or a double, they are copied on every assignment, copied
onto the stack to pass as arguments, and copied onto the stack when
returned as method or property results. This makes perfect sense for
ints, doubles, and even DateTimes: I have never run into a situation in
which I want to change every single variable in my program that holds
the value 5 to now hold the value 7. Every variable has its own copy of
the value, and changing one variable doesn't affect any other one. In
fact, for most values "changing the value" makes no sense at all: to
change what a variable holds you assign a new value.

Is this the kind of behaviour that is appropriate for something like a
"Branch"? Branches have identities: you can sensibly talk about "Branch
15" in our company. When I change some quality of Branch 15, it's
perfectly reasonable to assume (or desire) that every other variable
that holds (a reference to) Branch 15 will see that change as well. Do
I want a Branch to be copied on every assignment, copied onto the stack
for method calls, and copied onto the stack for method returns? Do I
want a system in which it's impossible, or near-impossible to have a
change to a Branch 15 stored in one variable affect the Branch 15
that's held by other variables in other parts of my system? I don't
think so.

..NET structs are tremendously useful in rare cases. In those
particular, peculiar situations they are indispensible. In almost every
other situation they are unnecessary. I see nothing in this problem
that says that the OP's Branch type is one of those rare circumstances
in which value semantics are useful. As Jon said, classes (that is,
reference semantics) should be the default choice. structs (value
semantics) should be employed only when there's a compelling reason to
do so. I see no such reason here.

However, I said that there were two reasons.

The second is that the OP self-identified as a newbie. IMHO,
programmers new to .NET should steer far clear of structs. They are
very, very unlikely to run into one of those rare circumstances in
which value semantics are a good idea. They are much, much more likely
to misapply structs and then wonder why their programs act strangely.
At best this will result in some confusion followed by a decision to
use classes instead; at worst this will result in the incorrect
conclusion that C# makes no sense and therefore sucks.

Take the OP's problem, for example. Göran suggested using an ArrayList
to hold the Branches. This is the simplest design, especially for a new
programmer to follow. Imagine the OP's confusion when they design their
Branch like this:

public struct Branch
{
private int _id;
private ArrayList _itemList;

public Branch(int branchId)
{
this._id = branchId;
this._itemList = new ArrayList();
}

public AddItem(string item1, string item2, string item3)
{
string[] items = new string[3];
items[0] = item1;
items[1] = item2;
items[2] = item3;
}
}

Again, a simple, straightforward design. With one catch: imagine the
OP's surprise when this doesn't work:

public static void Main()
{
ArrayList branchList = new ArrayList();

... some sort of loop to read branches here ...
Branch aBranch = new Branch(id);
branchList.Add(aBranch);
... some sort of loop to read items here ...
aBranch.AddItems(item1, item2, item3);
}

Imagine the consternation when the OP discovers that all of the
branches in the array list have zero items attached to them. Why? What
happened? What kind of stupid language is this, anyway?

Change "public struct Branch" to "public class Branch" and it works.

Experienced .NET programmers with a firm grasp of value semantics
versus reference semantics will, of course, be able to figure out why.
Newbie programmers will, generally speaking, not... not without alot of
pain and research.

If you want to read more about struct versus class, see the following
threads:

http://groups.google.com/group/micro...3bcc64b8438f65

http://groups.google.com/group/micro...862a7d7d6a914c

May 10 '06 #9

P: n/a
Sorry. In my haste I wrote the Branch struct incorrectly. The correct
code follows:

public struct Branch
{
private int _id;
private ArrayList _itemList;
public Branch(int branchId)
{
this._id = branchId;
this._itemList = new ArrayList();
}

public AddItem(string item1, string item2, string item3)
{
this._itemList.Add(item1);
this._itemList.Add(item2);
this._itemList.Add(item3);
}
}

May 10 '06 #10

P: n/a
Sigh. I even gave an incorrect link at the bottom of my post. I'm
having a bad day.

Just search this newsgroup for "struct vs class". You'll get lots of
hits.

May 11 '06 #11

P: n/a
Seems to work good so far. I have alot more to do yet.
I used a Hashtable to store the objects created by my class in.
I can reference any Branch I need at any time with a little code.
Now I need to learn a little recursion, another head swimmer. Maybe a
loop will work better.

Some good information here. Thanks!

May 11 '06 #12

P: n/a
"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...
OK... let's try this again.
First of all, make Branch a class, not a struct.
I'm curious -- why did you advise that?


<Snip an excellent explanation of why to prefer class over struct>

Nicely written Bruce.
I find that this is a MAJOR source of confusion for the C/C++ folks (I
was one of them).
They tend to think of structs as lightweight classes.
Perhaps struct was not such a good name for these thingamabobs.
Oh well, Nice job
Bill
May 11 '06 #13

P: n/a
On Thu, 11 May 2006 01:05:25 GMT, "Bill Butler" <qw****@asdf.com>
wrote:
I find that this is a MAJOR source of confusion for the C/C++ folks (I
was one of them).
They tend to think of structs as lightweight classes.
Perhaps struct was not such a good name for these thingamabobs.


I don't see the confusion here. Structs _are_ lightweight classes in
C#, as opposed to C++ where struct is just another name for class that
implies a different default visibility.

The problem is that the mechanism that provides for this
lightweight-ness has a few gotchas that C++ people will miss.
--
http://www.kynosarges.de
May 11 '06 #14

P: n/a
> Structs _are_ lightweight classes in C#.

Sorry. I categorically disagree with this. I agree with Bill: maybe
"struct" wasn't such a good keyword.

Structs are "lightweight" only in the sense that they avoid garbage
collection, but that's a consideration only when they're used in
massive numbers. That's why (IMHO) Microsoft chose to make Point and
Rectangle as structs rather than as classes: because they anticipated
that they would be used in massive numbers, and they wanted to avoid
the consequent overhead allocating and collecting them off the heap.

However, structs are _heavyweight_ where assignment, argument passing,
and method/property returns are concerned. It is possible to _degrade_
the performance of your program by changing classes to structs because
of all the consequent copying.

So saying that structs are "lightweight classes" is misleading: using a
struct may lead to performance gains, or may lead to performance
losses.

For my part, I find that the whole "efficiency" / "lightweight versus
heavyweight" arguing is way down the list of reasons why you would want
to make something a struct rather than a class. It is far, far more
common to want a struct because you want _value semantics_, because the
thing you're making really should act like a value, not distinct
objects each with its own identity. That's why I cringe when I hear it
said that structs are "classes-lite": while there is some truth in that
statement (with the aforementioned caveats), it omits the principal
reason why you would choose one over the other.

May 11 '06 #15

P: n/a
>Structs are "lightweight" only in the sense that they avoid garbage
collection,


There's more right? like a failure to participate in inheritance etc. When
viewed from that perspective, it is lighter than a class. Lighter is a good
choice of words because it means that there is enough similarity so that the
struct is not a totally new entity but enough difference such that it does
bring benefit. Here is a complete light definition that works well
http://www.jaggersoft.com/pubs/Struc...%20differences

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
-------------------------------------------------------

"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@q12g2000cwa.googlegr oups.com...
Structs _are_ lightweight classes in C#.


Sorry. I categorically disagree with this. I agree with Bill: maybe
"struct" wasn't such a good keyword.

Structs are "lightweight" only in the sense that they avoid garbage
collection, but that's a consideration only when they're used in
massive numbers. That's why (IMHO) Microsoft chose to make Point and
Rectangle as structs rather than as classes: because they anticipated
that they would be used in massive numbers, and they wanted to avoid
the consequent overhead allocating and collecting them off the heap.

However, structs are _heavyweight_ where assignment, argument passing,
and method/property returns are concerned. It is possible to _degrade_
the performance of your program by changing classes to structs because
of all the consequent copying.

So saying that structs are "lightweight classes" is misleading: using a
struct may lead to performance gains, or may lead to performance
losses.

For my part, I find that the whole "efficiency" / "lightweight versus
heavyweight" arguing is way down the list of reasons why you would want
to make something a struct rather than a class. It is far, far more
common to want a struct because you want _value semantics_, because the
thing you're making really should act like a value, not distinct
objects each with its own identity. That's why I cringe when I hear it
said that structs are "classes-lite": while there is some truth in that
statement (with the aforementioned caveats), it omits the principal
reason why you would choose one over the other.

May 11 '06 #16

P: n/a
"Chris Nahr" <ch************@kynosarges.de> wrote in message
news:hh********************************@4ax.com...
On Thu, 11 May 2006 01:05:25 GMT, "Bill Butler" <qw****@asdf.com>
wrote:
I find that this is a MAJOR source of confusion for the C/C++ folks
(I
was one of them).
They tend to think of structs as lightweight classes.
Perhaps struct was not such a good name for these thingamabobs.


I don't see the confusion here. Structs _are_ lightweight classes in
C#, as opposed to C++ where struct is just another name for class that
implies a different default visibility.

The problem is that the mechanism that provides for this
lightweight-ness has a few gotchas that C++ people will miss.


Ahhhh, but that is exactly my point.
In C++, even though classes and structs only differ in their default
visibility, they tend not to be used interchangeably. Structs tend to
be used when the developer doesn't need inheritance (data holders).
There is no good reason to prefer the struct over the class, but it does
seem to be the convention.
So these well meaning developers come to C# and use structs just like
they do in C++ and they get weird behavior. Take for example
MyStruct * mystruct = new MyStruct(); //C++
MyStruct mystruct = new MyStruct(); //C#

In C++ the return from new is a pointer to the object. You get reference
semantics when you construct a struct with the new operator. If you had
wanted value semantics you would have instantiated it without new
MyStruct mystruct; // C++
In C++, you created a MyStruct (called a c'tor and everything)
The same statement in C# gets you an uninitialized reference.

In C++ it is a piece of cake to switch between value an reference
semantics.

MyStruct mystruct;
Foo(mystruct); // copies the struct
Mystruct * pStruct = &mystruct;
Bar(pStruct ); // just passes the pointer;

C# classes and structs *Feel* alot like their older brethren at a casual
glance. It is natural to assume that they will behave similarly. The
inherent "Valueness" of the C# structs is a BIG gotcha to C++ ---> C#
convert.

This is why I feel that it is a good idea to avoid structs until you
understand the pitfalls.

Bill




May 12 '06 #17

P: n/a
<"Alvin Bruney" <www.lulu.com/owc>> wrote:
Structs are "lightweight" only in the sense that they avoid garbage
collection,


There's more right? like a failure to participate in inheritance etc. When
viewed from that perspective, it is lighter than a class. Lighter is a good
choice of words because it means that there is enough similarity so that the
struct is not a totally new entity but enough difference such that it does
bring benefit. Here is a complete light definition that works well
http://www.jaggersoft.com/pubs/Struc...%20differences


That's a great page, but it doesn't mention the word "light" anywhere.

Structs aren't "lighter" than classes - they're just different. Lighter
is *not* a good choice of words, because it makes people think that
when they need something to be efficient, they should pick a struct.
That's a really, really bad reason to choose a struct unless you're
*very* clean on all the consequences.

Value semantics versus reference semantics can't be reduced to
"lightweight" or "heavyweight", and doing so just causes confusion.
I've seen lots of people choose structs because they're supposedly
lightweight, without understanding what's going on at all, or why they
can *sometimes* bring efficiency benefits along with the other semantic
differences.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 12 '06 #18

P: n/a
On Fri, 12 May 2006 07:22:45 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
Structs aren't "lighter" than classes - they're just different. Lighter
is *not* a good choice of words, because it makes people think that
when they need something to be efficient, they should pick a struct.


But they should! That's a correct description! Microsoft introduced
structs in the first place because they are more efficient than
classes for small data containers such as numerical types, and they
are more efficient because their implement is in fact comparatively
lightweight -- no heap allocation (for locals), no object wrapper.

What you guys are talking about are really just faulty assumptions on
the part of programmers who believe in silver bullets and don't stop
to think "gee, if structs are all-around better than classes then why
do classes exist at all?".

Because once you do stop to ask yourself that question it's pretty
blatantly obvious that a lightweight class is going to have _some_
disadvantage that prevents it from being used universally...

There's a lot to learn when you switch from C++ to C#. The meaning of
"struct" is just one part of it, and not a particularly difficult one
IMO. Maybe it can serve as a useful reminder that the C++ language
has not in fact monopolized the naming and semantics of all
programming constructs, the belief of its fans to the contrary. :)
--
http://www.kynosarges.de
May 12 '06 #19

P: n/a
Chris Nahr <ch************@kynosarges.de> wrote:
Structs aren't "lighter" than classes - they're just different. Lighter
is *not* a good choice of words, because it makes people think that
when they need something to be efficient, they should pick a struct.
But they should!


No, they shouldn't. They should consider whether they want reference or
value semantics, work out how large the type will be, find out whether
it's actually going to be a bottleneck anyway, whether making it a
value type will actually make it more efficient, etc.
That's a correct description!
No, it's not. They're different beasts, and calling one a lightweight
version of the other doesn't in any way convey the important
differences between them.

<snip>
There's a lot to learn when you switch from C++ to C#. The meaning of
"struct" is just one part of it, and not a particularly difficult one
IMO.


I agree it's not very difficult, but it's not aided in any way by
calling structs lightweight classes, any more than learning the
differences between int and float would be aided by calling int a
lightweight float.

In short, I haven't seen that description do any *good*, but I've
certainly seen it confuse people before now.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 12 '06 #20

P: n/a
On Fri, 12 May 2006 10:16:59 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
No, they shouldn't. They should consider whether they want reference or
value semantics, work out how large the type will be, find out whether
it's actually going to be a bottleneck anyway, whether making it a
value type will actually make it more efficient, etc.
But what are you talking about here other than the (important)
difference between value and refernce semantics? You're talking about
size and speed -- and imply that people should look into structs where
the size of the type is small and speed is a requirement.

Which is exactly what the term "lightweight class" conveys.
No, it's not. They're different beasts, and calling one a lightweight
version of the other doesn't in any way convey the important
differences between them.
I simply disagree here. In my opinion, the term "lightweight class"
nicely conveys both the implementation and the intended use of a
struct. So does the term "struct" itself insofar as structs are used
as simple data containers in C++ which is also the typical struct use.

It's the responsibility of the programmer to figure out any other
important differences. You can't seriously expect to pack the entire
reference documentation in a name or an adjective.

What other name would you suggest, anyway?
I agree it's not very difficult, but it's not aided in any way by
calling structs lightweight classes, any more than learning the
differences between int and float would be aided by calling int a
lightweight float.


That's a poor analogy because floats are stored in the same way as
ints, take up the same storage space, and these days aren't even much
slower than ints...
--
http://www.kynosarges.de
May 12 '06 #21

P: n/a
I think the lightweightedness terminology is a lot more friendly, al beit,
less technically appealing for the semantic die-hards out there. Generally,
the definition has served its purpose well because it indicates to some
extent that a class should be preferred over a struct except in
circumstances where performance may be a concern. The fact of the matter is
structs and classes are related by blood and so, one is usually described
within the context of the other. Adjusting the literature to define
otherwise is unappealing and fails to take the lineage into account.

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
-------------------------------------------------------

"Chris Nahr" <ch************@kynosarges.de> wrote in message
news:53********************************@4ax.com...
On Fri, 12 May 2006 10:16:59 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
No, they shouldn't. They should consider whether they want reference or
value semantics, work out how large the type will be, find out whether
it's actually going to be a bottleneck anyway, whether making it a
value type will actually make it more efficient, etc.


But what are you talking about here other than the (important)
difference between value and refernce semantics? You're talking about
size and speed -- and imply that people should look into structs where
the size of the type is small and speed is a requirement.

Which is exactly what the term "lightweight class" conveys.
No, it's not. They're different beasts, and calling one a lightweight
version of the other doesn't in any way convey the important
differences between them.


I simply disagree here. In my opinion, the term "lightweight class"
nicely conveys both the implementation and the intended use of a
struct. So does the term "struct" itself insofar as structs are used
as simple data containers in C++ which is also the typical struct use.

It's the responsibility of the programmer to figure out any other
important differences. You can't seriously expect to pack the entire
reference documentation in a name or an adjective.

What other name would you suggest, anyway?
I agree it's not very difficult, but it's not aided in any way by
calling structs lightweight classes, any more than learning the
differences between int and float would be aided by calling int a
lightweight float.


That's a poor analogy because floats are stored in the same way as
ints, take up the same storage space, and these days aren't even much
slower than ints...
--
http://www.kynosarges.de

May 12 '06 #22

P: n/a
>> That's a correct description!
No, it's not. They're different beasts, and calling one a lightweight
version of the other doesn't in any way convey the important
differences between them.


Precisely. Dead on.

I realize that Chris has already responded to Jon's analogy, but it's
so good that I have to repeat it: Does that then mean that it's OK to
refer to ints as "lightweight floats"? Or floats as "heavyweight ints"?

The problem with that description is that it says nothing about what
really matters: why you would choose one over the other. Ints offer
precision but no fractional content. Floating point offers fractional
content but is not precise. Unless the programmer understands both what
they can store _and_ how precise they are, he can't make an informed
decision as to which one he needs.

For me, all of the stuff about structs not participating in
inheritance, and that their "lineage" comes from classes (whatever that
means) is secondary to the principal reason why you would choose one
over the other: value semantics versus reference semantics. Even the
"allocated on the stack" versus "allocated on the heap" distinction
isn't really terribly important. What is terribly important is that
structs are _copied_ constantly, whereas classes aren't.

So far I have _never_ found a situation so compelling that I decided to
use a "struct" for efficiency reasons, or because it doesn't
participate in the inheritance hierarchy. I have several structs in the
system on which I work, and all of them are there because the type
requires value semantics. Jon mentioned _one_ case in which he created
a struct type for efficiency reasons. I assume that he has created
others for other reasons, but perhaps I'm wrong.

This whole conversation reminds me of asking whether databases or flat
files are "more efficient". The question sidesteps the primary reasons
why you would choose one over the other: either answer, yes or no,
would be incomplete and misleading.

May 12 '06 #23

P: n/a
> The problem is that the mechanism that provides for this lightweight-ness has a few gotchas that C++ people will miss.

Funny. I see it from completely the other way around.

C# contains something called "struct" that is very useful, but
substantially different from "class" and substantially different from
the "struct" in C++, although it has some passing similarities to the
latter. Unfortunately, by using the same keyword for something new, the
language practically guarantees that C++ programmers will assume that
"struct" in C# is supposed to be like "struct" in C++ and will attempt
to use it as they did before, with less than satisfactory results.

I prefer to think of the C# struct as a way to construct my own value
types that act like "int" or "double". I consider its similarities to
C++'s "struct" to be artifacts of its value semantics and neither
terribly interesting nor terribly useful.

May 12 '06 #24

P: n/a
"Bruce Wood" <br*******@canada.com> wrote:
I realize that Chris has already responded to Jon's analogy, but it's
so good that I have to repeat it: Does that then mean that it's OK to
refer to ints as "lightweight floats"? Or floats as "heavyweight ints"?


Because structs have value-semantics, if you send a struct to one
thread and also to another, then the two threads will have their own
copies which won't interfere. Therefore, and in the spirit of
misleading terminology, I propose that we call structs
"thread-safe lightweight classes"
:)

--
Lucian
May 12 '06 #25

P: n/a
Now we're getting somewhere. :)

May 12 '06 #26

P: n/a
Note that I suggested to make it a class before adding methods to it. :)

I agree with your clear example of the risks of using structs. They can
be tricky, especially if they contain objects.

As a rule, there is very rarely any reason to make it a struct if it
contains objects, don't you say?

Bruce Wood wrote:
Take the OP's problem, for example. Göran suggested using an ArrayList
to hold the Branches. This is the simplest design, especially for a new
programmer to follow. Imagine the OP's confusion when they design their
Branch like this:

public struct Branch
{
private int _id;
private ArrayList _itemList;

public Branch(int branchId)
{
this._id = branchId;
this._itemList = new ArrayList();
}

public AddItem(string item1, string item2, string item3)
{
string[] items = new string[3];
items[0] = item1;
items[1] = item2;
items[2] = item3;
}
}

Again, a simple, straightforward design. With one catch: imagine the
OP's surprise when this doesn't work:

public static void Main()
{
ArrayList branchList = new ArrayList();

... some sort of loop to read branches here ...
Branch aBranch = new Branch(id);
branchList.Add(aBranch);
... some sort of loop to read items here ...
aBranch.AddItems(item1, item2, item3);
}

Imagine the consternation when the OP discovers that all of the
branches in the array list have zero items attached to them. Why? What
happened? What kind of stupid language is this, anyway?

Change "public struct Branch" to "public class Branch" and it works.

Experienced .NET programmers with a firm grasp of value semantics
versus reference semantics will, of course, be able to figure out why.
Newbie programmers will, generally speaking, not... not without alot of
pain and research.

May 12 '06 #27

P: n/a
Chris Nahr wrote:
Structs _are_ lightweight classes in C#


No, structs are not classes, not even lightweight classes, and they
don't behave like classes. In most aspects structs are more lightweight
than classes, but that doesn't make the struct a leightweight version of
the class.
May 12 '06 #28

P: n/a
Chris Nahr <ch************@kynosarges.de> wrote:
No, they shouldn't. They should consider whether they want reference or
value semantics, work out how large the type will be, find out whether
it's actually going to be a bottleneck anyway, whether making it a
value type will actually make it more efficient, etc.
But what are you talking about here other than the (important)
difference between value and refernce semantics? You're talking about
size and speed -- and imply that people should look into structs where
the size of the type is small and speed is a requirement.

Which is exactly what the term "lightweight class" conveys.


Except that it concentrates on the less important part of it. It's like
describing the difference between a mouse and a planet as "one is
bigger than another". While that's true, it's not the most important
thing by a long shot.
No, it's not. They're different beasts, and calling one a lightweight
version of the other doesn't in any way convey the important
differences between them.


I simply disagree here. In my opinion, the term "lightweight class"
nicely conveys both the implementation and the intended use of a
struct.


It doesn't indicate the value/reference semantics *at all*. Those are
the most important semantics - any description which doesn't indicate
that there is such a difference is misleading IMO.
So does the term "struct" itself insofar as structs are used
as simple data containers in C++ which is also the typical struct use.

It's the responsibility of the programmer to figure out any other
important differences. You can't seriously expect to pack the entire
reference documentation in a name or an adjective.
No - so why try, given that some people *will* take the simplistic
description at face value and try to apply it without going into any
more detail?
What other name would you suggest, anyway?


I would avoid using any simplistic term, preferring to refer people to
an article/book/whatever which explains the difference properly.
I agree it's not very difficult, but it's not aided in any way by
calling structs lightweight classes, any more than learning the
differences between int and float would be aided by calling int a
lightweight float.


That's a poor analogy because floats are stored in the same way as
ints, take up the same storage space, and these days aren't even much
slower than ints...


Except they're fundamentally different in what they store. The biggest
difference between them is conceptual, not performance.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 12 '06 #29

P: n/a
<"Alvin Bruney" <www.lulu.com/owc>> wrote:
I think the lightweightedness terminology is a lot more friendly, al beit,
less technically appealing for the semantic die-hards out there.
That's like saying that the following statements are "more friendly"
than the truth:

o "Structs are stored on the stack, classes are stored on the heap"
o "Reference type parameters are passed by reference by default"

Neither of these is correct. Both *have* caused confusion - confusion
which has manifested itself on this very newsgroup, several times. Both
are generally defended on the grounds of being "friendlier", with
similar name-calling of those who view correctness as important as
"semantic die-hards" and the like.

I don't see what's "die-hard" about wanting to give a correct
impression, rather than misleading people. It's not like the difference
between reference semantics and value semantics is an unimportant minor
point.
Generally, the definition has served its purpose well because it
indicates to some extent that a class should be preferred over a
struct except in circumstances where performance may be a concern.
Not for me. I generally prefer lightweight things unless I have a need
for the "heaviness" of the alternative. If I only knew the "structs are
lightweight classes" definition, I'd treat structs as the default. Good
job I know better, isn't it? Why bother with a short description if you
really need a longer one in order to understand the difference at all
in the first place? Why not just refer people to a more detailed
comparison?
The fact of the matter is structs and classes are related by blood
Care to put that in concrete terms?
and so, one is usually described within the context of the other.
It's fine to compare and contrast - but just using such a misleading
description is a really, really bad idea IMO.
Adjusting the literature to define otherwise is unappealing and fails
to take the lineage into account.


I'd prefer to use correct definitions than ones which take lineage into
account and then mislead people.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 12 '06 #30

P: n/a

The fact of the matter is structs and classes are related by blood
Care to put that in concrete terms?

How about spec terms? Spec 1.7 C#
"Like classes, structs are data structures that can contain data members and
function members..."

The preceding implies similarity does it not? The fact that these are both
data structures shows some close family relation.

In fact, spec 11.3 goes so far as to delineate the difference between
structs and classes. Why? Because they are so similar that one may be
confused for the other hence the reason for the literature. (That is my
interpretation of spec 11.3)

I sincerely do not believe that anyone in here thinks that a struct is a
class or a type of class for that matter. I believe it to be a manner of
speaking only. I cannot argue against the technical merit for requiring a
clear distinction in terminology. However, my position is that it is not
sufficiently disturbing to warrant such drastic changes to the literature.
Since the majority of programmers who have a real need for structs do so
because they have a driving need. That need can only be filled firstly if
the programmer has a deep understanding of the difference.

I also fail to see the argument framed to include C++ programmer confusion.
After all, destructor syntax is horribly confusing to C++ programmers. But
we did survive this bout and Jon did not complain about the destructor
syntax either. So why now? We need to focus instead on structs and classes
inside C#. Those migrating to C# need to use an appropriate resource and be
guided accordingly while understanding that material presented in the
newsgroup is not guaranteed accurate and should be taken with a good dose of
salt and a pinch of asprin.
That's like saying that the following statements are "more friendly"
than the truth: That is a horrible analogy. And for that matter, both sides have presented
horrible analogies that were self-serving. These analogies are without merit
because they were all carefully constructed to eluminate one side of the
argument - this one in particular is equally guilty.
I don't see what's "die-hard" about wanting to give a correct
impression, rather than misleading people. Because it is tedious. It's the long way around the track when a shorter,
simpler explanation can work just as well for the majority of the 10 million
programmers out there.
I'd prefer to use correct definitions than ones which take lineage into
account and then mislead people. I'd agree here with you but I believe that the struct vs class argument is
unique and should benefit from certain semantic liberties. Most people
understand classes but few understand structs well. There is merit in
explaining one in terms of the other. Notice this is the approach the
specification takes and then proceeds to differentiate the two. There's
nothing wrong with that. Or would you prefer to rewrite the specs?

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
-------------------------------------------------------

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om... <"Alvin Bruney" <www.lulu.com/owc>> wrote:
I think the lightweightedness terminology is a lot more friendly, al
beit,
less technically appealing for the semantic die-hards out there.


That's like saying that the following statements are "more friendly"
than the truth:

o "Structs are stored on the stack, classes are stored on the heap"
o "Reference type parameters are passed by reference by default"

Neither of these is correct. Both *have* caused confusion - confusion
which has manifested itself on this very newsgroup, several times. Both
are generally defended on the grounds of being "friendlier", with
similar name-calling of those who view correctness as important as
"semantic die-hards" and the like.

I don't see what's "die-hard" about wanting to give a correct
impression, rather than misleading people. It's not like the difference
between reference semantics and value semantics is an unimportant minor
point.
Generally, the definition has served its purpose well because it
indicates to some extent that a class should be preferred over a
struct except in circumstances where performance may be a concern.


Not for me. I generally prefer lightweight things unless I have a need
for the "heaviness" of the alternative. If I only knew the "structs are
lightweight classes" definition, I'd treat structs as the default. Good
job I know better, isn't it? Why bother with a short description if you
really need a longer one in order to understand the difference at all
in the first place? Why not just refer people to a more detailed
comparison?
The fact of the matter is structs and classes are related by blood


Care to put that in concrete terms?
and so, one is usually described within the context of the other.


It's fine to compare and contrast - but just using such a misleading
description is a really, really bad idea IMO.
Adjusting the literature to define otherwise is unappealing and fails
to take the lineage into account.


I'd prefer to use correct definitions than ones which take lineage into
account and then mislead people.

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

May 12 '06 #31

P: n/a
> As a rule, there is very rarely any reason to make it a struct if it contains objects, don't you say?

No... I have a struct (value type) that contains a reference to an
object (reference type). It's called a Measure, and it is a quantity
(value) coupled with a unit of measure (object instance). The trick is
that the object instance is immutable. This struct allows me to
represent, and perform mathematics and conversions on quantities that
have attached units of measure. So, for example, I can add "5 meters"
to "3 feet" and get a sensible answer.

It's freaky when a value type contains a reference to a changeable
object. That would be a bit weird, because then you would have values
that _could_ change simultaneously when you changed some aspect of one:
sort of hybrid reference and value semantics.

However, holding a reference to an immutable object instance doesn't
present any problems at all.

May 12 '06 #32

P: n/a
On 12 May 2006 08:30:22 -0700, "Bruce Wood" <br*******@canada.com>
wrote:
So far I have _never_ found a situation so compelling that I decided to
use a "struct" for efficiency reasons


I don't believe you. You may have very well never _defined_ your own
structs but you're using them all the time: Int32, Single, Double!

And you can only use them, and not have your program grind to a halt
(as would happen if it was written in Smalltalk) because these data
types are not implemented as regular classes, but as lightweight
variants of regular classes. Also known as structs. QED.
--
http://www.kynosarges.de
May 12 '06 #33

P: n/a
On Fri, 12 May 2006 19:12:35 +0200, Göran Andersson <gu***@guffa.com>
wrote:
No, structs are not classes, not even lightweight classes, and they
don't behave like classes.


Funny, I could have sworn you could create instances of structs, and
put fields in them, and define methods on them...
--
http://www.kynosarges.de
May 12 '06 #34

P: n/a
Now we're splitting hairs. You know what I meant.

May 12 '06 #35

P: n/a

"Chris Nahr" <ch************@kynosarges.de> wrote in message
news:mt********************************@4ax.com...
On 12 May 2006 08:30:22 -0700, "Bruce Wood" <br*******@canada.com>
wrote:
So far I have _never_ found a situation so compelling that I decided
to
use a "struct" for efficiency reasons


I don't believe you. You may have very well never _defined_ your own
structs but you're using them all the time: Int32, Single, Double!

And you can only use them, and not have your program grind to a halt
(as would happen if it was written in Smalltalk) because these data
types are not implemented as regular classes, but as lightweight
variants of regular classes. Also known as structs. QED.


Yes, Bruce already brought this point up in his original argument.
The problem is with the following statement:

"A struct is essentially a lightweight class."

That sentence has a different meaning to a C++ programmer.
So they hear that sentence and ASSUME that it is lightweight in the same
sense as in C++. So then they turn around and write a struct with 20
string members and wonder why it performs like a pig. After all they did
create the struct like this

MyStruct mystruct = new MyStruct()
Foo(mystruct);

This code LOOKS like it should have reference semantics.
Most C++ coders ARE surprised to learn that it doesn't.

So I say "Prefer classes over structs".
Classes are almost always more efficient than structs.
If your class falls into that small minority...go ahead, make it a
struct.
But do it with your eyes open to the gotchas.

Bill


May 13 '06 #36

P: n/a
<"Alvin Bruney" <www.lulu.com/owc>> wrote:
The fact of the matter is structs and classes are related by blood
Care to put that in concrete terms?

How about spec terms? Spec 1.7 C#
"Like classes, structs are data structures that can contain data members and
function members..."

The preceding implies similarity does it not?


Similarity, yes. "Related by blood"? That's certainly not backed up by
the spec.
The fact that these are both
data structures shows some close family relation.
Not particularly - partly because "family relation" isn't a well-
defined term in computer science. That's why I asked what you really
meant by it.
In fact, spec 11.3 goes so far as to delineate the difference between
structs and classes. Why? Because they are so similar that one may be
confused for the other hence the reason for the literature. (That is my
interpretation of spec 11.3)
They're certainly similar enough to warrant a comparison. They're not
similar enough to talk about one as being a lightweight or heavyweight
version of the other.
I sincerely do not believe that anyone in here thinks that a struct is a
class or a type of class for that matter. I believe it to be a manner of
speaking only. I cannot argue against the technical merit for requiring a
clear distinction in terminology. However, my position is that it is not
sufficiently disturbing to warrant such drastic changes to the literature.
What literature? I'm talking about people casually referring to structs
as "lightweight classes" as if this passed on any worthwhile
information. Instead, it leaves a misleading impression.
Since the majority of programmers who have a real need for structs do so
because they have a driving need. That need can only be filled firstly if
the programmer has a deep understanding of the difference.
Absolutely - and calling structs lightweight classes does *not* give
that deep understanding or even hint that deeper understanding is
required. People make decisions based solely on the fact that structs
have been described as lightweight classes. They shouldn't, but they
do. That's human nature.
I also fail to see the argument framed to include C++ programmer confusion.
After all, destructor syntax is horribly confusing to C++ programmers. But
we did survive this bout and Jon did not complain about the destructor
syntax either. So why now? We need to focus instead on structs and classes
inside C#. Those migrating to C# need to use an appropriate resource and be
guided accordingly while understanding that material presented in the
newsgroup is not guaranteed accurate and should be taken with a good dose of
salt and a pinch of asprin.
So you're saying that describing a struct as a lightweight class isn't
accurate, but that's okay because no-one should trust what's said on a
newsgroup anyway? Okay then - maybe I should start calling structs
"heavyweight classes" then. After all, it can't do any harm, can it?
That's like saying that the following statements are "more friendly"
than the truth: That is a horrible analogy.
I don't think so. In all cases:
a) The "simplified" version tells a tiny part of the story
b) The tiny part of the story which is told distracts from the bigger
picture
c) People have been confused by the "simplified" version
And for that matter, both sides have presented
horrible analogies that were self-serving. These analogies are without merit
because they were all carefully constructed to eluminate one side of the
argument - this one in particular is equally guilty.
Can you refute any of the above points?
I don't see what's "die-hard" about wanting to give a correct
impression, rather than misleading people. Because it is tedious. It's the long way around the track when a shorter,
simpler explanation can work just as well for the majority of the 10 million
programmers out there.
Except it doesn't. We've seen people be confused by calling structs
lightweight classes. Do you really want to contribute to confusion? I'm
not suggesting that you write a huge long explanation every time. I'm
suggesting that you find a resource which explains it properly, and
reference that instead.
I'd prefer to use correct definitions than ones which take lineage into
account and then mislead people.

I'd agree here with you but I believe that the struct vs class argument is
unique and should benefit from certain semantic liberties.
I don't believe it's unique, but I believe it's so important that it
absolutely *can't* benefit from semantic liberties. It's not that
complicated - it *gets* complicated when people take semantic liberties
so that when someone wants to find out the truth, they've got to
"unlearn" the myths they've heard first.
Most people understand classes but few understand structs well.
And the fact that people keep referring to structs as "lightweight
classes" is one of the contributing factors to that lack of
understanding.
There is merit in explaining one in terms of the other.
I've never disputed that.
Notice this is the approach the specification takes and then proceeds
to differentiate the two. There's nothing wrong with that. Or would
you prefer to rewrite the specs?


You seem to have created a straw man argument, as though I've been
arguing against comparing structs and classes. I never have. I've just
said that calling structs lightweight classes and leaving it at that
creates a misleading impression, and that's a bad thing to do. The
specs *don't* do that, of course - they give details, which is what
I've been arguing for the whole time.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 13 '06 #37

P: n/a
Chris Nahr <ch************@kynosarges.de> wrote:
No, structs are not classes, not even lightweight classes, and they
don't behave like classes.


Funny, I could have sworn you could create instances of structs, and
put fields in them, and define methods on them...


There are similarities - but there are big differences too. Calling one
a lightweight version of the other gives a false impression as to how
similar they are.

I repeat: this description has confused people in the past. Many
people, in fact. Why continue using a description which has proved to
be confusing?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 13 '06 #38

P: n/a
>From my point of view, the answer to this whole "should we call structs
'lightweight classes'?" argument is this very newsgroup.

I haven't been here long... maybe a year or so. In that time, every two
weeks at most someone posts here asking, "Why not use structs all the
time, since they're more efficient?" (Where "more efficient" is, at
least in these posters' minds, equivalent to "lighter weight".) or "Why
doesn't my program work...? I'm using structs." (Invariably
incorrectly, as a result of thinking of them as "lightweight classes"
and nothing more.) In the last while we had two such questions within a
week. I have no statistics, but my impression is that it's one of the
FAQ's in this newsgroup.

Every time the problem is that the poster thought that structs were
just "classes-lite" and didn't understand that there was anything more
to know than that.

Do I believe that calling structs "lightweight classes" is utterly
without merit? No, I don't: the two-word definition does contain some
truth. However, in the context of all of this confusion (and there's
plenty of confusion out there)... where the number one misconception
about structs is that they are "classes lite" _and that's all they
are_... do I think that calling them "lightweight classes" is a
_helpful_ definition? No, I do not: it contributes to the already
rampant confusion.

Myself, I prefer another two-word definition: structs are "value
types". This at least gives newbies pause: "Hey, I don't know what that
means." Well, then it's time to do some digging and find out. The
problem with "lightweight classes" is that newbies say to themselves,
"Oh, I know what that means" when in fact they don't. I'd rather save
them the pain of finding out the hard way (like I did).

May 13 '06 #39

P: n/a
On 12 May 2006 16:41:40 -0700, "Bruce Wood" <br*******@canada.com>
wrote:
Now we're splitting hairs. You know what I meant.


Sure, but what you meant is unrelated to the question of calling
structs "lightweight classes" or pointing out their greater efficiency
as small data containers.

Even though you never saw a reason to create a _user-defined_ struct
for performance reasons, you're still constantly profiting from all
the _predefined_ structs that were created for performance reasons.
Your programs might well be unusably slow if not for those structs!
--
http://www.kynosarges.de
May 13 '06 #40

P: n/a
On Sat, 13 May 2006 07:51:42 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
I repeat: this description has confused people in the past. Many
people, in fact. Why continue using a description which has proved to
be confusing?


Because it's technically accurate, in terms of both purpose and
implementation, and being confused by it merely reflects a lack of
knowledge about the CLR. Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.

Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)
--
http://www.kynosarges.de
May 13 '06 #41

P: n/a
Chris Nahr wrote:
On Fri, 12 May 2006 19:12:35 +0200, Göran Andersson <gu***@guffa.com>
wrote:
No, structs are not classes, not even lightweight classes, and they
don't behave like classes.


Funny, I could have sworn you could create instances of structs, and
put fields in them, and define methods on them...


You can define properties and methods in an interface to, but that
doesn't make it a "lightweight class".

Classes and structs have similarities, but that doesn't make them the
same. A class can have properties and methods, but that doesn't mean
that anything that can have properties and methods is a class.

Horses have four legs and a tail, but everything that has four legs and
a tails aren't horses...
May 13 '06 #42

P: n/a
Chris Nahr wrote:
On Sat, 13 May 2006 07:51:42 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
I repeat: this description has confused people in the past. Many
people, in fact. Why continue using a description which has proved to
be confusing?
Because it's technically accurate, in terms of both purpose and
implementation,


No, it's not. It's a simplified description that gives the illusion of
conveying more insight in the matter than it does.

Saying that a struct is a "lightweight class" needs to be followed by an
explanation what that means. If it isn't, it's not very much short of a lie.
and being confused by it merely reflects a lack of
knowledge about the CLR.
But calling a struct a "leightweight class" makes people believe that
they don't need any deeper knowledge about the CLR, as it makes them
think that they know what a struct really is.
Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.
A term is not apropriate if it over-simplifies things so much that it
gives people a false sense of knowledge. Few people will try to learn
more than they believe that they need.
Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)


Yes, he might. But he wouldn't feed you simplified explanations that
would make you feel that it was a lot simpler than it is.
May 13 '06 #43

P: n/a
Bruce Wood wrote:
As a rule, there is very rarely any reason to make it a struct if it contains objects, don't you say?


No... I have a struct (value type) that contains a reference to an
object (reference type). It's called a Measure, and it is a quantity
(value) coupled with a unit of measure (object instance). The trick is
that the object instance is immutable. This struct allows me to
represent, and perform mathematics and conversions on quantities that
have attached units of measure. So, for example, I can add "5 meters"
to "3 feet" and get a sensible answer.

It's freaky when a value type contains a reference to a changeable
object. That would be a bit weird, because then you would have values
that _could_ change simultaneously when you changed some aspect of one:
sort of hybrid reference and value semantics.

However, holding a reference to an immutable object instance doesn't
present any problems at all.


Yes, immutable objects would be the exception.
May 13 '06 #44

P: n/a
Chris Nahr <ch************@kynosarges.de> wrote:
I repeat: this description has confused people in the past. Many
people, in fact. Why continue using a description which has proved to
be confusing?
Because it's technically accurate, in terms of both purpose and
implementation


I wouldn't even say that though. If you have two types which each have
20 instance fields (all ints for the sake of argument). The only
difference between them is that one is a class and one is a struct. You
need to use these types as parameters and return values frequently. Now
which feels like a heavyweight type and which feels lighter?
and being confused by it merely reflects a lack of
knowledge about the CLR. Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.
Where exactly is "lightweight class" defined in the first place? It's
not in the C# spec as far as I'm aware - the C# spec gives details
instead of relying on inappropriately brief descriptions.

I don't think it's particularly helpful to use terminology which you
*know* causes confusion on the grounds that people should learn more
about the subject so as to avoid being confused. We get the situation
where there are two types of reader: those who don't already know what
a struct is (who will be confused by your description) and those who do
(who won't gain anything by your description). Where exactly is the
benefit?
Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)


I don't see why that makes it a good answer.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 13 '06 #45

P: n/a
On Sat, 13 May 2006 12:42:21 +0200, Göran Andersson <gu***@guffa.com>
wrote:
You can define properties and methods in an interface to, but that
doesn't make it a "lightweight class".
Correct, instead it makes the interface a purely abstract class since
you can't create an instance of it. Purely abstract classes is how
you emulate interfaces in C++ which doesn't have this construct.
Classes and structs have similarities, but that doesn't make them the
same. A class can have properties and methods, but that doesn't mean
that anything that can have properties and methods is a class.


You might want to read an introduction to OOP, and also look up the
base class of System.ValueType in the MSDN documentation.
--
http://www.kynosarges.de
May 13 '06 #46

P: n/a
On Sat, 13 May 2006 15:57:42 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
Because it's technically accurate, in terms of both purpose and
implementation
I wouldn't even say that though. If you have two types which each have
20 instance fields (all ints for the sake of argument). The only
difference between them is that one is a class and one is a struct. You
need to use these types as parameters and return values frequently. Now
which feels like a heavyweight type and which feels lighter?


Practical experience with a given struct has no bearing on what I
said. Structs exist for the purpose of being more lightweight than
classes, and that purpose is reflected in their implementation.
Where exactly is "lightweight class" defined in the first place? It's
not in the C# spec as far as I'm aware - the C# spec gives details
instead of relying on inappropriately brief descriptions.
First, a literal reference from an authoritative source:

MSDN Library, "C# Programming Guide":
"A struct can be considered a lightweight class, ideal for creating
data types that store small amounts of data, and does not represent a
type that might later be extended via inheritance."
http://msdn2.microsoft.com/en-us/library/ms173109.aspx

Interestingly, C++/CLI uses the keywords "value class" as opposed to
"ref class" = reference type. Here's a paper on the subject by Rex
Jaeschke, standards editor for C++/CLI, CLI, and C#:

Rex Jaeschke, "A lightweight class mechanism", Dr. Dobb's Journal:
"The value class is a lightweight C++/CLI class mechanism that is
particularly useful for reasonably small data structures that have
value semantics."
http://www.ddj.com/dept/cpp/184401955

And here are a number of references that call structs "lightweight"
although they avoid the term "class" since it's already used as a
synonym for "reference type" in the context of the explanation:

MSDN Library, "C# Programmer's Reference":
"The struct type is suitable for representing lightweight objects such
as Point, Rectangle, and Color. Although it is possible to represent a
point as a class, a struct is more efficient in some scenarios."
http://msdn.microsoft.com/library/de...tructTypes.asp

Jeff Richter, "CLR via C#", Microsoft Press, page 124:
"To improve performance for siple, frequently used types, the CLR
offers light-weight types called value types."

Steven Holzner, "Object-Oriented Programming in C#", Sams:
"Structs in C# are like lightweight versions of classes. [...] They
take up fewer resources in memory, so when you've got a small,
frequently used class, give some thought to using a struct instead."
http://www.samspublishing.com/articl...&seqNum=9&rl=1

Fahad Gilani, MSDN Magazine, "C# in Depth" series:
"For scientific applications, value types can be fast, efficient, and
an excellent choice over reference types whenever possible. In the
next section, I'll take a look at one of the many uses of user-defined
lightweight data types in scientific programming."
http://msdn.microsoft.com/msdnmag/is...3/ScientificC/

Other sources do not use the literal term "lightweight" but still
highlight the cheapness and efficiency of value types as compared to
reference types when introducing the concept:

Eric Gunnerson & Nick Wienholt, "A Programmer's Introduction to C#",
Apress, page 79:
"Sometimes, however, it may be desirable to crate an object that
behaves like one of the built-in types -- one that's cheap and fast to
allocate and doesn't have the overhead of references."

Don Box with Chris Sells, "Essential .NET vol. 1", Addison-Wesley,
p.133:
"In particular, instances of value types do not carry the storage
overhead of full-blown objects. This makes value types useful in
scenarios where the costs of an object would otherwise be
prohibitive."

So I hope we can agree that structs are, in fact, commonly introduced
as lightweight types in the literature. The motivation is in fact to
have a type that is less expensive than a reference type.
I don't think it's particularly helpful to use terminology which you
*know* causes confusion on the grounds that people should learn more
about the subject so as to avoid being confused. We get the situation
where there are two types of reader: those who don't already know what
a struct is (who will be confused by your description) and those who do
(who won't gain anything by your description). Where exactly is the
benefit?


Like the cited authors, I don't share your opinion that readers who
don't already know about structs will invariably be confused about the
"lightweight" moniker. Again, I think it's accurate and helpful.

When I was learning C# I found this characterisation appropriate and
useful in forming a mental concept of the purpose and implementation
of structs. The copy-on-pass semantics are always highlighted in the
vicinity of such an introduction, so I never had a problem with that.

Frankly, I don't see why we should give any regard to people who run
off and implement something (badly) after seeing a single adjective-
noun pair, as if that would explain everything! Of course it doesn't,
but what kind of programmer would assume that it does?
--
http://www.kynosarges.de
May 13 '06 #47

P: n/a
Chris Nahr wrote:
On Sat, 13 May 2006 12:42:21 +0200, Göran Andersson <gu***@guffa.com>
wrote:
You can define properties and methods in an interface to, but that
doesn't make it a "lightweight class".
Correct, instead it makes the interface a purely abstract class since
you can't create an instance of it.


No, it doesn't. You can inherit mutliple interfaces, but not multiple
classes, no matter how abstract they are.
Purely abstract classes is how
you emulate interfaces in C++ which doesn't have this construct.
Classes and structs have similarities, but that doesn't make them the
same. A class can have properties and methods, but that doesn't mean
that anything that can have properties and methods is a class.


You might want to read an introduction to OOP, and also look up the
base class of System.ValueType in the MSDN documentation.


An introduction to OOP? Well, I might have read one when I started using
OOP in the late eighties, has it changed much?

Why would I look up the base class of System.ValueType? Don't you think
that I know what the base class of System.ValueType is?
May 13 '06 #48

P: n/a
Chris Nahr wrote:
On Fri, 12 May 2006 07:22:45 +0100, Jon Skeet [C# MVP]
<sk***@pobox.com> wrote:
Structs aren't "lighter" than classes - they're just different. Lighter
is *not* a good choice of words, because it makes people think that
when they need something to be efficient, they should pick a struct.
But they should! That's a correct description! Microsoft introduced
structs in the first place because they are more efficient than
classes for small data containers such as numerical types, and they
are more efficient because their implement is in fact comparatively
lightweight -- no heap allocation (for locals), no object wrapper.


This is just silly, Chris. Structures in programming languages have been around
for longer than C, longer than object orientation, longer than C++, and WAY
longer than Microsoft. M/S did not "introduce" structs - and if anything the C#
usage perverts the concept.
What you guys are talking about are really just faulty assumptions on
the part of programmers who believe in silver bullets and don't stop
to think "gee, if structs are all-around better than classes then why
do classes exist at all?".

Because once you do stop to ask yourself that question it's pretty
blatantly obvious that a lightweight class is going to have _some_
disadvantage that prevents it from being used universally...

There's a lot to learn when you switch from C++ to C#. The meaning of
"struct" is just one part of it, and not a particularly difficult one
IMO. Maybe it can serve as a useful reminder that the C++ language
has not in fact monopolized the naming and semantics of all
programming constructs, the belief of its fans to the contrary. :)


Not everybody comes to C# from C++. Some may come from C. When I code "struct
Foo {...};" in a function body I am most likely declaring a local value type.
But when I code "typedef struct {...} *pFoo;" in a header I am describing the
layout of storage that I expect to access via a reference (aka a pointer).

It's likewise with older constructs such as PL/1 "based" storage and even IBM
360 DSECTs. These were abstract descriptions of storage, templates if you will.
(Yikes! - another loaded word.) Once the structure was "instantiated" by
allocating memory and returning a pointer that pointer got used much like a C#
reference.

Anyhow, although it's surely *historically* inaccurate to call a structure a
"lightweight class" this is not the real difficulty. If I describe classes as
"structures extended with methods", have I conveyed anything useful about what a
class is or how objects are used? Or have I just propagated a misleading
analogy which obscures the underlying real difference. Calling a structure a
lightweight class gives a misleading impression of how it behaves in certain key
ways.

C# structs look confusingly too much like classes as it is IMO, what with having
constructors and being instantiated with the "new" keyword. They are neither
true classes, nor do they really behave like the constructs formerly known as
structs either. I think I agree with those who wish C# style structs had just
been called something else entirely.

Regards,
-rick-
May 13 '06 #49

P: n/a
Chris Nahr <ch************@kynosarges.de> wrote:
I wouldn't even say that though. If you have two types which each have
20 instance fields (all ints for the sake of argument). The only
difference between them is that one is a class and one is a struct. You
need to use these types as parameters and return values frequently. Now
which feels like a heavyweight type and which feels lighter?
Practical experience with a given struct has no bearing on what I
said. Structs exist for the purpose of being more lightweight than
classes, and that purpose is reflected in their implementation.


Except when you use them as parameters, return values, or use
assignment.

I would agree if you'd just said that structs are lighter weight
allocation and release, and can use less memory when a single value is
only used in one place. However, just calling them "lightweight
classes" implies (to me at least) that they're lighter *in general*
which clearly isn't true in reality. There are plenty of ways in which
using them is "heavier" than using classes, so the generalisation isn't
accurate IMO.
Where exactly is "lightweight class" defined in the first place? It's
not in the C# spec as far as I'm aware - the C# spec gives details
instead of relying on inappropriately brief descriptions.


First, a literal reference from an authoritative source:

MSDN Library, "C# Programming Guide":
"A struct can be considered a lightweight class, ideal for creating
data types that store small amounts of data, and does not represent a
type that might later be extended via inheritance."
http://msdn2.microsoft.com/en-us/library/ms173109.aspx


Are, MSDN - that authoritative source which claimed for a long time
that System.Decimal was a fixed-point number type.

It's even wrong about saying its "ideal for creating data types that
store small amounts of data" - again, that ignores the whole value
semantics vs reference semantics which is surely at the heart of the
differences between structs and classes. If you want reference
semantics, you should use classes even if there's only a small amount
of data.
Interestingly, C++/CLI uses the keywords "value class" as opposed to
"ref class" = reference type.
The CLI spec uses different terminology for various things. This
shouldn't come as much of a surprise, although it occasionally causes a
lot of confusion.

<snip>
And here are a number of references that call structs "lightweight"
although they avoid the term "class" since it's already used as a
synonym for "reference type" in the context of the explanation:
<snip>

I could give plenty of examples of early Java textbooks which claimed
that Java passed objects by reference - that wouldn't make them any
less confusing or any more accurate.
So I hope we can agree that structs are, in fact, commonly introduced
as lightweight types in the literature. The motivation is in fact to
have a type that is less expensive than a reference type.
I agree that they're commonly introduced as lightweight types. Now, do
you want me to find you a similar number of posts from people who have
been confused by that terminology? Just because lots of people use a
certain description doesn't make it accurate or useful. Heck, lots of
people talk about ASCII as if it had 256 characters in it. Are they
right too, just because there are lots of them?
I don't think it's particularly helpful to use terminology which you
*know* causes confusion on the grounds that people should learn more
about the subject so as to avoid being confused. We get the situation
where there are two types of reader: those who don't already know what
a struct is (who will be confused by your description) and those who do
(who won't gain anything by your description). Where exactly is the
benefit?


Like the cited authors, I don't share your opinion that readers who
don't already know about structs will invariably be confused about the
"lightweight" moniker. Again, I think it's accurate and helpful.


It's accurate when the "lightweight" bit is qualified to allocation.
It's possibly helpful when it's in the context of a wider description.
On newsgroups, however, it's often left as the *whole* of the
description of structs, which is what I really object to.
When I was learning C# I found this characterisation appropriate and
useful in forming a mental concept of the purpose and implementation
of structs. The copy-on-pass semantics are always highlighted in the
vicinity of such an introduction, so I never had a problem with that.
No, those semantics *aren't* always highlighted - that's the problem.
Often structs are *just* described as "lightweight classes", and that's
where people get confused.
Frankly, I don't see why we should give any regard to people who run
off and implement something (badly) after seeing a single adjective-
noun pair, as if that would explain everything! Of course it doesn't,
but what kind of programmer would assume that it does?


So you're happy to confuse people by using an overly simplistic
description, knowing that some people *will* take that as sufficient
evidence to base decisions on? I prefer to do my utmost to make sure I
won't leave people with the wrong impression.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 14 '06 #50

61 Replies

This discussion thread is closed

Replies have been disabled for this discussion.