Re: Struct vs Class
Hi Marin,
Thanks for clearing that up. I didn't realize that you were agreeing with
Bruce when you wrote, "aliasing".
But I think DictionaryEntry proves that it may be appropriate to define a
struct that has references to mutable objects. When DictionaryEntry contains
references, the value of the DictionaryEntry itself is the relationship
between the references. It doesn't matter whether the objects being
referenced can be mutated or not. Therefore, structs that assign value to
references or their relationships should have no problem referencing mutable
objects.
Nullable<Tis an immutable value type.
That is a strange error - quite possibly a bug.
--
Dave Sexton
"Martin Z" <martin.zarate@ gmail.comwrote in message
news:1162235821 .307961.321930@ h48g2000cwc.goo glegroups.com.. .
Hi Marin,
structs containing references to mutable objects is what I meant by
"aliasing" - that is, if I have a struct I may assume that everything I
do with it will be copy-semantics... however, if it contains a
reference to a mutable class (say a stringbuilder) then if I make
changes to that stringbuilder, then all copies (not just the object I'm
accessing to make the changes) will see that, which is unexpected
behaviour for a struct. That is, an alias where we expect a copy.
"aliasing" - that is, if I have a struct I may assume that everything I
do with it will be copy-semantics... however, if it contains a
reference to a mutable class (say a stringbuilder) then if I make
changes to that stringbuilder, then all copies (not just the object I'm
accessing to make the changes) will see that, which is unexpected
behaviour for a struct. That is, an alias where we expect a copy.
Bruce when you wrote, "aliasing".
But I think DictionaryEntry proves that it may be appropriate to define a
struct that has references to mutable objects. When DictionaryEntry contains
references, the value of the DictionaryEntry itself is the relationship
between the references. It doesn't matter whether the objects being
referenced can be mutated or not. Therefore, structs that assign value to
references or their relationships should have no problem referencing mutable
objects.
And yes, I agree that Nullables _should_ be valuetype, and likely are
in implementation - I just thought that they were reference-types
because errors thrown by the XmlSerializer informed me that they were
reference types... which is likely just the serializer getting very
confused by the concept of a nullable value-type.
in implementation - I just thought that they were reference-types
because errors thrown by the XmlSerializer informed me that they were
reference types... which is likely just the serializer getting very
confused by the concept of a nullable value-type.
That is a strange error - quite possibly a bug.
--
Dave Sexton
"Martin Z" <martin.zarate@ gmail.comwrote in message
news:1162235821 .307961.321930@ h48g2000cwc.goo glegroups.com.. .
structs containing references to mutable objects is what I meant by
"aliasing" - that is, if I have a struct I may assume that everything I
do with it will be copy-semantics... however, if it contains a
reference to a mutable class (say a stringbuilder) then if I make
changes to that stringbuilder, then all copies (not just the object I'm
accessing to make the changes) will see that, which is unexpected
behaviour for a struct. That is, an alias where we expect a copy.
>
And yes, I agree that Nullables _should_ be valuetype, and likely are
in implementation - I just thought that they were reference-types
because errors thrown by the XmlSerializer informed me that they were
reference types... which is likely just the serializer getting very
confused by the concept of a nullable value-type.
>
Dave Sexton wrote:
>
"aliasing" - that is, if I have a struct I may assume that everything I
do with it will be copy-semantics... however, if it contains a
reference to a mutable class (say a stringbuilder) then if I make
changes to that stringbuilder, then all copies (not just the object I'm
accessing to make the changes) will see that, which is unexpected
behaviour for a struct. That is, an alias where we expect a copy.
>
And yes, I agree that Nullables _should_ be valuetype, and likely are
in implementation - I just thought that they were reference-types
because errors thrown by the XmlSerializer informed me that they were
reference types... which is likely just the serializer getting very
confused by the concept of a nullable value-type.
>
Dave Sexton wrote:
>Hi Martin,
>>
>>
>What do you mean by "aliasing behaviour"?
>>
>>
>I think Nullable<Tshoul d be a value type just like DictionaryEntry . They
>each assign a value to the objects that they contain - nullability or hash
>entry, respectively.
>>
>Although nullability is only useful for value types, which is why I suspect
>that you can't make a Nullable<string >, for example.
>>
>But hash entries can be anything, including mutable objects.
>DictionaryEntr y
>is just a value: the relationship between a key and its corresponding
>value.
>If the key or the value are object references then the value of the hash
>entry
>itself is simply the relationship between the two references. If another
>DictionaryEntr y contains the same key and value references, then the values
>of
>the DictionaryEntri es are equal.
>>
>Nullable<Tan d DictionaryEntry do not represent tangible objects, they
>represent assignable values. It helps some people to think of values as
>conceptual and objects as physical, like me!
>>
>>
>I've never actually created an instance of DictionaryEntry though. I've
>only
>used it in iterators so I'm not sure the mutability was necessary. I
>assume
>the author(s) made it mutable due to some internal implementation
>constraints
>that I don't feel like searching for right now :)
>>
>But just to clear things up, my response to Bruce wasn't about the
>mutability
>of DictionaryEntry , it was about the mutability of the objects that it
>references. That's what I assumed Bruce meant when he wrote, "structs that
>contain references to _mutable_ objects", although reading it
>out-of-context
>now I can see why you thought that.
>>
>>
>>
>I won't argue that :)
>>
>--
>Dave Sexton
>>
>"Martin Z" <martin.zarate@ gmail.comwrote in message
>news:116223260 6.318831.243760 @b28g2000cwb.go oglegroups.com. ..
>>
obviously if you're using structs because
you want value-type semantics then it doesn't matter what you stuff in
them (as long as they're immutable to avoid confusing aliasing
behaviour).
you want value-type semantics then it doesn't matter what you stuff in
them (as long as they're immutable to avoid confusing aliasing
behaviour).
>What do you mean by "aliasing behaviour"?
>>
Funny that nullables are value-type - I recently got an error from the
XmlSerializer where it complained that they were reference types, and
thus couldn't be XmlAttributes. That was just silly.
XmlSerializer where it complained that they were reference types, and
thus couldn't be XmlAttributes. That was just silly.
>I think Nullable<Tshoul d be a value type just like DictionaryEntry . They
>each assign a value to the objects that they contain - nullability or hash
>entry, respectively.
>>
>Although nullability is only useful for value types, which is why I suspect
>that you can't make a Nullable<string >, for example.
>>
>But hash entries can be anything, including mutable objects.
>DictionaryEntr y
>is just a value: the relationship between a key and its corresponding
>value.
>If the key or the value are object references then the value of the hash
>entry
>itself is simply the relationship between the two references. If another
>DictionaryEntr y contains the same key and value references, then the values
>of
>the DictionaryEntri es are equal.
>>
>Nullable<Tan d DictionaryEntry do not represent tangible objects, they
>represent assignable values. It helps some people to think of values as
>conceptual and objects as physical, like me!
>>
Anyhow, I think the reason DictionaryEntry is mutable is just because
people got really sick of saying new DictionaryEntry <MyKeyType,
MyValueType- not for any good technical reason.
people got really sick of saying new DictionaryEntry <MyKeyType,
MyValueType- not for any good technical reason.
>I've never actually created an instance of DictionaryEntry though. I've
>only
>used it in iterators so I'm not sure the mutability was necessary. I
>assume
>the author(s) made it mutable due to some internal implementation
>constraints
>that I don't feel like searching for right now :)
>>
>But just to clear things up, my response to Bruce wasn't about the
>mutability
>of DictionaryEntry , it was about the mutability of the objects that it
>references. That's what I assumed Bruce meant when he wrote, "structs that
>contain references to _mutable_ objects", although reading it
>out-of-context
>now I can see why you thought that.
>>
I think it's
hilarious that the structs have the nice immediate-setting semantics
for mutable structs
myStructClass foo;
foo.bar = 1;
foo.baz = 2;
//all parameters initialized, it's ready to use, no constructor
needed.
hilarious that the structs have the nice immediate-setting semantics
for mutable structs
myStructClass foo;
foo.bar = 1;
foo.baz = 2;
//all parameters initialized, it's ready to use, no constructor
needed.
but you can only use them with mutable structs anyways, making it
completely useless since MS says to never-ever-do-mutable-structs. I
want the readonly attribute to apply to property setters, and then
integrate that with the 3.0 Object Initializers so we can have some
non-excruciating syntax for immutables.
completely useless since MS says to never-ever-do-mutable-structs. I
want the readonly attribute to apply to property setters, and then
integrate that with the 3.0 Object Initializers so we can have some
non-excruciating syntax for immutables.
>I won't argue that :)
>>
>--
>Dave Sexton
>>
>"Martin Z" <martin.zarate@ gmail.comwrote in message
>news:116223260 6.318831.243760 @b28g2000cwb.go oglegroups.com. ..
Holy poop, DictionaryEntry is mutable? (off to MSDN).... Whoa. Oh,
and my comment about avoiding including value-types in structs was from
the optimization direction - obviously if you're using structs because
you want value-type semantics then it doesn't matter what you stuff in
them (as long as they're immutable to avoid confusing aliasing
behaviour).
>
Funny that nullables are value-type - I recently got an error from the
XmlSerializer where it complained that they were reference types, and
thus couldn't be XmlAttributes. That was just silly.
>
Anyhow, I think the reason DictionaryEntry is mutable is just because
people got really sick of saying new DictionaryEntry <MyKeyType,
MyValueType- not for any good technical reason. I think it's
hilarious that the structs have the nice immediate-setting semantics
for mutable structs
myStructClass foo;
foo.bar = 1;
foo.baz = 2;
//all parameters initialized, it's ready to use, no constructor
needed.
>
but you can only use them with mutable structs anyways, making it
completely useless since MS says to never-ever-do-mutable-structs. I
want the readonly attribute to apply to property setters, and then
integrate that with the 3.0 Object Initializers so we can have some
non-excruciating syntax for immutables.
>
Dave Sexton wrote:
>Hi Bruce,
>>
Of course, structs that contain references to _mutable_
objects can lead to some awfully puzzling, nearly-unpredictable
behaviour, so I wouldn't recommend that. :-)
>>
>DictionaryEntr y is one that doesn't conform to that idea, however.
>>
>--
>Dave Sexton
>>
>"Bruce Wood" <brucewood@cana da.comwrote in message
>news:116222971 1.383330.47510@ b28g2000cwb.goo glegroups.com.. .
>
Martin Z wrote:
>Bruce, My understanding is that, if designed to be entirely immutable
>and containing no events, then there is almost no visible difference
>between a class and a struct.
>
Apparently so. I'm trying to think of differences in behaviour between
an immutable class and a struct, and I can't. Of course, it's Monday
morning. I could be wrong.
>
One would have to overload == appropriately (and, one presumes, the
other mathematical and comparison operators), but apart from that I
can't think of any hitches. Of course, the temptation with a class
would be to make it mutable, but that's just a temptation, not a
given.
>
>The struct is primarily a speed-optimization - access to
>stack-variables
>is
>much faster.
>
I wouldn't state that as the primary speed benefits of structs. I
consider the primary speed benefit of structs being that they don't
need to be garbage-collected. So, if you are doing extensive
calculations that involve the creation of myriad intermediate results
then structs are a better choice because objects created on the heap
have to be GC'd.
>
However, this is only one consideration in whether to make something a
struct or a class, and not even the most important. The most important
consideration, IMHO, is whether the thing you want to create displays
_value semantics_. There are lots of discussions in this newsgroup
about struct vs class and value vs reference semantics.
>
>Hence, structs should only contain other valuetypes.
>
No, I disagree. For example, I have a struct called a Measure, which
contains a decimal quantity and a unit of measure. UnitOfMeasure is
a(n
immutable) reference type. I think that our disagreement on this point
goes back to the speed benefits of structs: I see storage on the stack
as a side-effect of using structs, not as a motivation for using
structs, and so I don't see anything wrong with structs that contain
references. Of course, structs that contain references to _mutable_
objects can lead to some awfully puzzling, nearly-unpredictable
behaviour, so I wouldn't recommend that. :-)
>
>
and my comment about avoiding including value-types in structs was from
the optimization direction - obviously if you're using structs because
you want value-type semantics then it doesn't matter what you stuff in
them (as long as they're immutable to avoid confusing aliasing
behaviour).
>
Funny that nullables are value-type - I recently got an error from the
XmlSerializer where it complained that they were reference types, and
thus couldn't be XmlAttributes. That was just silly.
>
Anyhow, I think the reason DictionaryEntry is mutable is just because
people got really sick of saying new DictionaryEntry <MyKeyType,
MyValueType- not for any good technical reason. I think it's
hilarious that the structs have the nice immediate-setting semantics
for mutable structs
myStructClass foo;
foo.bar = 1;
foo.baz = 2;
//all parameters initialized, it's ready to use, no constructor
needed.
>
but you can only use them with mutable structs anyways, making it
completely useless since MS says to never-ever-do-mutable-structs. I
want the readonly attribute to apply to property setters, and then
integrate that with the 3.0 Object Initializers so we can have some
non-excruciating syntax for immutables.
>
Dave Sexton wrote:
>Hi Bruce,
>>
Of course, structs that contain references to _mutable_
objects can lead to some awfully puzzling, nearly-unpredictable
behaviour, so I wouldn't recommend that. :-)
>>
>DictionaryEntr y is one that doesn't conform to that idea, however.
>>
>--
>Dave Sexton
>>
>"Bruce Wood" <brucewood@cana da.comwrote in message
>news:116222971 1.383330.47510@ b28g2000cwb.goo glegroups.com.. .
>
Martin Z wrote:
>Bruce, My understanding is that, if designed to be entirely immutable
>and containing no events, then there is almost no visible difference
>between a class and a struct.
>
Apparently so. I'm trying to think of differences in behaviour between
an immutable class and a struct, and I can't. Of course, it's Monday
morning. I could be wrong.
>
One would have to overload == appropriately (and, one presumes, the
other mathematical and comparison operators), but apart from that I
can't think of any hitches. Of course, the temptation with a class
would be to make it mutable, but that's just a temptation, not a
given.
>
>The struct is primarily a speed-optimization - access to
>stack-variables
>is
>much faster.
>
I wouldn't state that as the primary speed benefits of structs. I
consider the primary speed benefit of structs being that they don't
need to be garbage-collected. So, if you are doing extensive
calculations that involve the creation of myriad intermediate results
then structs are a better choice because objects created on the heap
have to be GC'd.
>
However, this is only one consideration in whether to make something a
struct or a class, and not even the most important. The most important
consideration, IMHO, is whether the thing you want to create displays
_value semantics_. There are lots of discussions in this newsgroup
about struct vs class and value vs reference semantics.
>
>Hence, structs should only contain other valuetypes.
>
No, I disagree. For example, I have a struct called a Measure, which
contains a decimal quantity and a unit of measure. UnitOfMeasure is
a(n
immutable) reference type. I think that our disagreement on this point
goes back to the speed benefits of structs: I see storage on the stack
as a side-effect of using structs, not as a motivation for using
structs, and so I don't see anything wrong with structs that contain
references. Of course, structs that contain references to _mutable_
objects can lead to some awfully puzzling, nearly-unpredictable
behaviour, so I wouldn't recommend that. :-)
>
>
Comment