Difference between nullable class and nullable<> structure

G

gareth erskine-jones

The following comes from "Pro VB 2005 and the .NET 2.0 Platform", APress, by
Andrew Troelsen

Page 313 (Understanding Value Types and Reference Types):

"Specifically speaking, a .NET data type may be value-based or
reference-based. Value-based types, which include all numerical data types
(Integer, Double, etc.), as well as enumerations and structures, are
allocated on the stack."

Point #1:

Realizing that this is a C# NG, but also realizing the Greg used the VB .NET
term "structure", let me quote from page 123 (Programming Constructs):

"...structures do not have an identically named class representation in the
.NET library (that is there is no System.Structure class), but are
implicitly derived from System.ValueType."

and from page 314:

"...understand that .NET structures and enumerations are also value types.
Structures, as you may recall from Chapter 4, provide a way to achieve
bare-bones benefits of object orientation (i.e. , encapsulation) while
having the efficiency of stack-allocated data."

Your statement to Greg that the term "structure" to refer to a value type
was incorrect, is itself incorrect.

Point #2:

You stated:

"Any discussion of reference types and value types that begins by mentioning
the heap and the stack is, at a minimum, bound to fall short of precision,
and at worst will be extremely misleading."

The author (who you may have heard of and is considered to be quite an
expert in .NET) explains value-types to the reader in just the same way I
did. In fact, this approach is also taken in "Professional Visual Basic
2008", WROX. And, in fact, it is taken in just about every text I can find
on the subject.

I agree that the vast majority of books & documentation on this
subject do seem to follow the line you advocate, but I have to agree
with Peter that it is a misleading line to follow. I think it's
particularly revealing that in all of the discussion above, the real
semantic difference between value and reference types is not
mentioned.

It's perfectly possible for a programmer to use value and reference
types in c# without him being taught about the stack and the heap -
but if he doesn't know that when passing the former, a copy is made
(ie. it is passed by value) and when passing the latter, no copy is
made (it is passed by reference), then his code will be very
defective.

I don't think this is just a hypothetical situation. I can't, off
hand, remember when I saw a performance problem which had to be fixed
by switching from a reference type to a value type (obviously, this
does sometimes matter - I just don't think it happens very much). I
have seen lots of cases where there were subtle errors in code because
the passing semantics were not fully understood (e.g. implementing
Equals() on a value type is very different to a reference type).
Despite what you may personally belive, I (and just a few notable others)
feel that it is appropriate to discuss reference and value types in the
context of the stack and the heap and that it is not necessary to explore
all the gory details during the initial exposure to the concepts.

The clincher for me is that it's possible to explain all of the
semantic differences between the two without ever mentioning the stack
or heap, which suggests that it's actually the details of where they
are allocated which are the unnecessary gory details. Indeed - as Eric
Lippert has pointed out, it's perfectly possible to implement the CLI
without implementing value types on the stack.

GSEJ
 
G

gareth erskine-jones

Peter Duniho said:
Scott said:
[...]
Well, that says a lot about your ability to be open-minded and see a
point from someone else's point of view. You just don't care. You're
right and no matter what anyone says, you're right. [...]

Just FYI: at this point, the third time in a just a handful of sentences
you've attempted to put words in my mouth, I've stopped reading. You
clearly don't care to carry on any semblance of a mature, factual
discussion.

That's fine, but let's at least have the record clear. This is what my
reply above was based on, you saying:

" I have not heard of that author, but even if I did, I don't care."

I'm content to let anyone with enough time on their hands read this thread
and decide who's presented a mature, rational agrument with facts and who
hasn't.

Very couragous :)

GSEJ
 
G

Göran Andersson

gareth said:
It's perfectly possible for a programmer to use value and reference
types in c# without him being taught about the stack and the heap -
but if he doesn't know that when passing the former, a copy is made
(ie. it is passed by value) and when passing the latter, no copy is
made (it is passed by reference), then his code will be very
defective.

Eventhough I am sure that you understand how this works, you got the
details and terms mixed up. ;)

Both value types are reference types are actually by default passed by
value. For a value type it simply means that the value is copied onto
the stack. For a reference type it means that a copy of the reference is
placed on the stack.

Passing _by_ reference is not the same as passing _a_ reference. The ref
keyword is used to pass a parameter by reference, and that will pass a
reference to the variable instead of a copy of it's value.

However, the most useful information here is of course that an object is
not copied when you pass it as a parameter, as you correctly stated. :)
 
G

Gregory A. Beamer

Both value types are reference types are actually by default passed by
value. For a value type it simply means that the value is copied onto
the stack. For a reference type it means that a copy of the reference
is placed on the stack.

I think we are getting way too deep into the dirty details now. So much
so that the "technically correct" answer is more confusing than the
simpler explanation, which lacks technical accuracy.

It reminds me of a bunch of animals trying to see who can pee higher up
the tree.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
P

Peter Duniho

Gregory said:
I think we are getting way too deep into the dirty details now. So much
so that the "technically correct" answer is more confusing than the
simpler explanation, which lacks technical accuracy.

It is easy to be simple and technically accurate. Why sacrifice the
latter unnecessarily?
It reminds me of a bunch of animals trying to see who can pee higher up
the tree.

All due respect, you are being short-sighted and unnecessarily insulting.

Göran's comments are accurate, and a useful and important correction to
the exact phrasing used by the previous poster. Just as some often
confuse value types as something that is always allocated on the stack,
so too do some confuse the question of passing by reference or value
with the question of types that are reference or value.

It's such an important point that Jon Skeet has a whole article
dedicated to it:
http://www.yoda.arachsys.com/csharp/parameters.html
Peace and Grace,

When you are being judgmental -- such as accusing others of engaging in
a pissing contest (and to make matters worse, falsely in this case) --
you might want to leave out that part of your signature. It doesn't
really fit in those posts.

Pete
 
G

Gregory A. Beamer

It is easy to be simple and technically accurate.

If this thread is taken as an example, I would question this statement.

My feeling is that using a stack and heap in part of a discussion to
illustrate value types and reference types, although not 100%
technically correct, is okay. It is not my explanation I am "defending"
here, so I have no personal stake in the fight. I just don't see it as
something that damages a programmer for life.

You feel differently about it and apparently very strongly about it.

Thus we have reached an impasse.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
P

Peter Duniho

Gregory said:
If this thread is taken as an example, I would question this statement.

Straw man. There's nothing about this thread that is intended as an
example of presenting the concept of value types without reference to a
stack. More to the point, the extended discussion here is in no way an
attempt to do so, and thus is completely irrelevant as a counter-example
to my claim.
My feeling is that using a stack and heap in part of a discussion to
illustrate value types and reference types, although not 100%
technically correct, is okay.

Yes, you've made that clear.
It is not my explanation I am "defending"
here, so I have no personal stake in the fight. I just don't see it as
something that damages a programmer for life.

Then you haven't watched (as I have) as numbers of programmers fail to
understand what's important about value types (the copying behavior
inherent in them, for example) even as they assume incorrect things
about value types (thinking that they are always allocated on the stack,
for example).

The former is something that every C# programmer needs to know. There
are a number of examples of code in which failing to understand what a
value type actually is and how it works with respect to the copy vs.
reference behavior that will cause compilation difficulties at a minimum
(the compiler tries to catch and prevent the most obvious misuses), and
can result in hard-to-understand bugs at worst.

On the other hand, the vast majority of C# programmers can completely
ignore the fact that value types are under certain circumstances
allocated on the stack, without any detriment to their code at all.

This says something very clear and fundamental about which aspect of
value types is important and which is not.

But even more importantly, even if one wants to discuss value types in
the context of a stack, it's critical to _not make false statements_.
If one wants to introduce the relationship between value types and the
stack, fine. But do so in a _correct_ way. Making false statements
does nothing to improve a programmer's understanding of value types, and
in fact can create significant problems for them if they try to rely on
that false statement.
You feel differently about it and apparently very strongly about it.

I feel strongly enough to make a comment, and to resist efforts from
other people to make claims otherwise. If to you that is "very
strongly", so be it.
Thus we have reached an impasse.

And yet, you continue?

Pete
 
G

Gregory A. Beamer

I'm not the one saying we've reached an impasse.

Here is my final(?) two cents on this:

From a logical, not technical, standpoint, the analogy of the stack and the
heap work, even if technically the naming is incorrect. If we want to
totally abstract this concept, we could use X and Y for the boxes the types
are actually stored in and caps for the actual objects with lower case for
references:

X Y
--------------- ---------------
| | | |
| A | | |
| | | |
| b ===================> B |
| | | |
--------------- ---------------

In a class on .NET, I can draw the above in about five to ten seconds and
the student gets the basic point of how value types and reference types
work. I think Scott was aiming at the same idea, although he put the names
stack and heap above instead of X and Y. And Scott may have had an extreme
misunderstanding, but I still see no damage with the labels stack and heap,
as the developer likely to be "damaged" by it has many months, if not
years, before he is going to have to deep dive to the point where the
technical incorrectness of the idea is going to hurt him. And, many
developers I have met never dive that deep in their entire career.

But, if the labels stack and heap are the big issue, I think I have already
agreed with you that they are not great labels. If I have not, then I will
emphatically state X and Y are better on the drawing than stack and heap.

If I take this further, I can use the same drawing to explain why we need
deep copies when we are passing reference types around.


Shallow copy:

X Y
--------------- ---------------
| | | |
| A | | |
| | | |
| b1 ===================> B |
| b2 ===================> B |
| | | |
--------------- ---------------

Deep copy:


X Y
--------------- ---------------
| | | |
| A | | |
| | | |
| b1 ===================> B |
| b2 ================> B (copy) |
| | | |
--------------- ---------------

Perfect explanations of what is going on underneath the hood with 100%
technical accuracy? No, but the student now understands why the following
code would change his object instead of a copy.

public int SomeAction(MyObject obj)
{
obj.Property1 = null;
}

when this does not:

public int SomeAction(int i)
{
i++;
}

If teaching this much, in a very simple, visual manner, solves the problem,
then I see no reason to spend a good length of time explaining the
technical workings of the CLR. With time, and a good student, I will opt
for a deeper dive.

There are many cases where we don't dive deep and make statements that
techncially are incorrect. Consider the entire nature of connection
objects, which require a completely different understanding when one
considers the underlying "hidden" CLR controlled pool. But the average
developer does not need to dive there, so you explain it more simply.

In summary, I don't see the great damage done in using stack and heap,
although I would not choose these labels. I think you disagree. And, I also
think the entire thread, and all participants, are influencing the answers
you are firing back, which makes this thread even more cluttered.

I need to move on now. ;-)

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
P

Peter Duniho

Gregory said:
Here is my final(?) two cents on this:

From a logical, not technical, standpoint, the analogy of the stack and the
heap work, even if technically the naming is incorrect. If we want to
totally abstract this concept, we could use X and Y for the boxes the types
are actually stored in and caps for the actual objects with lower case for
references:

X Y
--------------- ---------------
| | | |
| A | | |
| | | |
| b ===================> B |
| | | |
--------------- ---------------

In a class on .NET, I can draw the above in about five to ten seconds and
the student gets the basic point of how value types and reference types
work.

One of the basic points, yes. It's a good start. But as you already
note, the diagram doesn't conflate the basic concept with "stack" and
"heap". You're simply proving my point: it's easy to explain the
concept without using "stack" and "heap" at all.
I think Scott was aiming at the same idea, although he put the names
stack and heap above instead of X and Y. And Scott may have had an extreme
misunderstanding, but I still see no damage with the labels stack and heap,
as the developer likely to be "damaged" by it has many months, if not
years, before he is going to have to deep dive to the point where the
technical incorrectness of the idea is going to hurt him. And, many
developers I have met never dive that deep in their entire career.

There is an immediate, if minor, problem if a developer thinks that a
value type member of a class is stored on the stack. It can lead to all
sorts of incorrect reasoning about the lifetime of either that value or
of the stack itself.

To me, the more important problem is that the explanation that leans
incorrectly on "stack" and "heap" is _also_ completely failing to
address what really makes value types interesting as separate from
reference types: that they operate in a "copy semantics" environment.

The fact that they are embedded in data structures is useful knowledge,
to be sure. But it's the copying of the data that from a language
standpoint is most interesting. Value types could be implemented in a
completely different way, and yet would still have usefulness as a
language construct.
[...]
If teaching this much, in a very simple, visual manner, solves the problem,
then I see no reason to spend a good length of time explaining the
technical workings of the CLR.

Nor I. That's never been the point, and I've said so more than once
(including in my immediately preceding post, to which you are replying).
I don't understand why you keep mentioning it as if it were.
[...]
There are many cases where we don't dive deep and make statements that
techncially are incorrect. Consider the entire nature of connection
objects, which require a completely different understanding when one
considers the underlying "hidden" CLR controlled pool.

I'm not aware of any _incorrect_ statements that have been made about
connection objects. Just because there's a connection pool underlying
the connection object class, that doesn't mean that someone is making a
false statement when discussing only the connection object class without
mention of the underlying connection pool.

Failing to describe all of the underlying details is not the same as
failing to make a correct statement. And I simply disagree that
"statements that technically are incorrect" are useful. It is much
better to simply not make a statement at all, than to make a statement
that is false.

And if someone _is_ going around explaining connection object classes by
making false statements about how they work, then it's my position
that's just as wrong as making false statements about value types.

Pete
 
G

Gregory A. Beamer

I'm not aware of any _incorrect_ statements that have been made about
connection objects. Just because there's a connection pool underlying
the connection object class, that doesn't mean that someone is making a
false statement when discussing only the connection object class without
mention of the underlying connection pool.

I have seen this stated many times: When you call Dispose() on a connection
object, the CLR will then clean it up on the next pass of the garbage
collector. Or similar.

Technically, this statement may or may not be correct, just like the stack
and heap argument. But, it gets the idea of Dispose() across.

I think, personally, we agree on more than we disagree. I just did not see
Scott's explanation as particularly insidious in line of the OP's question.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top