3

I've been reading up extensively on structs, and I have a decent understanding of where you would use them. One thing though bothers me is, no matter how much i read about it, I don't understand the immutability of structs.

I understand that, like strings, if you change them you essentially create an entirely new object in memory, but does this also hold for the values inside a struct. For instance:

public struct SomeValues
{
    public int AnInt;
    public float AFloat;
    public string AString;
}
public SomeValues[] ArrayOfValues;
private void SomeFunctionThatRunsContinuously()
{
    /*so for every value I change, do I essentially create a whole new instance
      of SomeValues?*/

    for (int i = 0; i < ArrayOfValues.Length; i++)
    {
        //Is this another struct?
        ArrayOfValues[i].AnInt++;

        //And then another again?
        ArrayOfValues[i].AFloat += 0.33f;

        /*I realise adding letters to a string is a horrible idea 
                       -- but is it WORSE to do it in a struct?*/

        ArrayOfValues[i].AString += "s";
    }
}

So for instance, if I had a struct which for instance was holding the coordinates of every person inside a 3D/2D space (coordinates were given as an example of when to use structs), and the positions of the people change and are updated inside a two/three int struct, from maybe an array, is that creating new structs because they're immutable?

user1044057
  • 211
  • 1
  • 2
  • 6
  • Structs are mutable. Making them immutable is prevailing wisdom, intended to keep new programmers out of trouble. Getting yourself into trouble is of course a good strategy to see what it is all about. Mutate away! – Hans Passant Dec 09 '11 at 12:31
  • Thank you for that, from what I've been reading I was mislead into thinking their 'make immutable' was 'it is immutable'. To be honest your advise makes more sense: hit those roadblocks so you can understand them THEN decide if it makes your code cleaner to make it immutable. – user1044057 Dec 09 '11 at 12:47
  • Related: [Are value types immutable by definition?](http://stackoverflow.com/questions/868411/are-value-types-immutable-by-definition). – Raymond Chen Dec 09 '11 at 13:22

4 Answers4

0

Structs are not immutable unless you make the fields in them Read Only.

public struct SomeValues 
{ 
    public readonly int AnInt; 
    public readonly float AFloat; 
    public readonly string AString; 
} 
Bas
  • 26,772
  • 8
  • 53
  • 86
  • But what if you have a member that's a reference type which doesn't have readonly fields? – kͩeͣmͮpͥ ͩ Dec 09 '11 at 12:09
  • @David - then you can not assign a new instance to that field, but you can (if not otherwise guarded) change values in the existing instance. – Hans Kesting Dec 09 '11 at 12:20
  • A `readonly` declaration does nothing to make a non-static field within a struct immutable. If `struct1` and `struct2` are of the same type, the statement `struct1 = struct2` will mutate all public and private fields of `struct1` (possibly simultaneously, or possibly in some arbitrary sequence) so as to match the corresponding fields of `struct2`; nothing within the definition of a structure type can change this behavior. – supercat Nov 30 '12 at 22:24
0

Struct are NOT immutable. New object in memory is created not when you change it, but when you assign it to different variable or pass as argument to some method.

Andrey
  • 1,601
  • 2
  • 11
  • 12
0

A struct is not immutable by default, it is just a very good idea to design the struct so that it acts immutable.

So for immutable structs/classes:

  • don't use public fields, use properties instead without a public setter. A private setter is fine, setting the backing-field (from the constructor) is also fine.
  • only allow values to be set through the constructor.
  • methods that appear to modify your struct should not modify it, they should return a new instance instead (think DateTime.AddYears).
Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
  • For point 1 Interestingly I heard the exact opposite: 'Generally, my feeling is that properties are highly overrated and fields terribly under-utilized' from http://blogs.msdn.com/b/ricom/archive/2006/08/31/733887.aspx Thanks, I didn't know structs weren't immutable, I only recently got my head around strings, so this is a bit confusing for me. – user1044057 Dec 09 '11 at 12:51
  • Some "things" need properties instead of fields. In this case you *need* to use properties so you can limit access (public read, private write). With fields that's impossible. – Hans Kesting Dec 09 '11 at 13:00
0

Structs are not immutable. While some people seem to think they should be, most of the reasons seem to fall into three categories:

  1. Struct methods are allowed to modify "this", whereas class methods are not; since it would be annoying to forbid the use of any and all methods on structs in read-only context--even those which don't in fact modify "this"--compilers instead handle method calls on read-only structs by making temporary copies of the structs and running the methods on those copies; any changes those methods might make disappear when the methods return.
  2. Some people don't realize that structs and classes behave differently.
  3. Some language features expect to make code transformations which may not work as well with mutable structs as they do with immutable structs or classes (mutable or immutable).

When value-type semantics make sense, use structs, especially when the entities in question are mutable. Consider:

struct fancyRect {public int left,top,width,height; ....other stuff.... };

... then within some code ...
  myList = List<fancyRect>; // Assume this list has been initialized somehow
  fancyRect tempRect = myList[0];
  tempRect.left += 5;
  myList[0] = tempRect;

The effects of the above code on the contents of myList can be fully ascertained with only the information supplied. It would be cleaner if properties could be exposed by reference, allowing myList[0].left += 5, but the code for structs is still clear and readable. Suppose tempRect were instead a class. What effect would the above code have? Could it have other effects? How would one have to code it to have the same semantics as with structs?

supercat
  • 77,689
  • 9
  • 166
  • 211