0

So I've been trying to get my head around this for weeks. I understand that structs are value types, and that classes are reference types. Where I get confused is the differences in behavior between the two.

For example: If I have a bag of potatoes, and each potato is a different size, shape, and weight... The bag would be a 'class' / reference type The potatoes would be a 'struct' / value type

Can my potatoes be a class, or do they have to be a struct as the values contained within are different?

Basically, the answer to that question will clear everything up for me.

Thank you!

mevans
  • 196
  • 2
  • 9
  • 12
    I highly doubt an answer to the question "Can my potatoes be a class?" clears up anything. – Henrik Jun 05 '13 at 12:34
  • 2
    Keep in mind the difference between a language-based value/reference type and a logical value/reference type. A `class` may logically be a value type and internally maintains reference concepts like equality/immutability/etc. – David Jun 05 '13 at 12:35
  • Consider the kinds of things that are structs: `int`, `float`, `decimal`, `Color`; and the kinds of things that are classes: `Form`, `Page`, `StackPanel`, `Socket`. – Wesley Wiser Jun 05 '13 at 12:36
  • This post explains very well when to use struct: http://stackoverflow.com/questions/521298/when-to-use-struct-in-c – Bidou Jun 05 '13 at 12:36
  • The main difference is in "copy semantics" : What exactly happens with `a = b;` depends on rev or value type. – H H Jun 05 '13 at 12:38
  • Okay. I was, for some reason under the assumption that... If potato was a 'class', that if i changed the weight of one potato, it would be reflected in all of them... – mevans Jun 05 '13 at 12:38
  • @user2455645 You're thinking of static vs. instance fields/methods. Has nothing to do with structs vs classes. – Rotem Jun 05 '13 at 12:39
  • Okay. Yeah. I think that somewhere along the line in the past couple of weeks my brain just froze up... This all makes sense now. – mevans Jun 05 '13 at 12:42
  • Your analogy with potatoes will not help you at all – David Heffernan Jun 05 '13 at 12:43
  • Elements (potatoes) that are contained inside some collection (bag) do *not* have to be of value type (struct). They could be of either value type or reference type (class). What made you think they had to be structs? – Jeppe Stig Nielsen Jun 05 '13 at 12:49

3 Answers3

5

If all that you're tracking about potatoes is their size, weight and shape, then answer the question - "if two potatoes have the same size, weight and shape, should they be considered to be the same?". And the answer to that question depends on your problem domain.

If they should be "the same", then you're comparing them by value and (generally) could/should be value types. If they should not be treated as "the same", then they should be reference types.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • 2
    I agree, although I think that the concept of identity is orthogonal to whether something is a reference or value type. I cite the example of the `string` class which is a reference type, but it behaves like a value type. But you did say "generally", so I agree. :) – Matthew Watson Jun 05 '13 at 12:42
  • Yeah, I wouldn't rely on discussing *comparing* since you can quite happily compare reference types by value... – Rawling Jun 05 '13 at 12:44
  • 2
    Having "Identity" conflicts with Value types. Not having Identity (string) does not conflict with Reference type. – H H Jun 05 '13 at 12:50
  • @HenkHolterman Yes, that makes the question easier to answer. If something has "identity" then it *cannot* be a value type. – Matthew Watson Jun 05 '13 at 12:54
1

If you want to take a Potato out of BagOfPotatoes and pass it around between other classes, if these classes were to modify the potato then it should be a reference type.

For example, BagOfPotatoes is passed to Chef.SortPotatoes(List<Potatoes> potatoes) and then goes on to Chef.SkinPotatoes(Potato potato) where the chef may skin the potato, setting Potato.IsSkinned.

  • If it were a reference type - Then any values changed would also be changed in BagOfPotatoes. i.e. Potato.IsSkinned = true

  • If it were a value type - Then BagOfPotatoes would still contain a bag with the original Potatos, i.e. Potato.IsSkinned = false

It deppends on whether or not you need to refer to a potato as an individual potato, where you chuck it about, and still talk about the same mashed up potato at the end of it (by reference). Or whether you only want to talk about the type of potato that it is (by value).

Drahcir
  • 11,772
  • 24
  • 86
  • 128
0

Anything that is a struct could be a class instead. The two behave subtly differently, but your "potatoes" could certainly be a class instead of a struct.

Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • 6
    I disagree, potatoes are inherently value types. I think you're confusing with tomatoes, which are definitely reference types. – Rotem Jun 05 '13 at 12:37