views:

125

answers:

1

In C#, if you have a struct like so:

struct Counter
{
    private int _count;

    public int Value
    {
        get { return _count; }
    }

    public int Increment()
    {
        return ++_count;
    }
}

And you have a program like so:

static readonly Counter counter = new Counter();

static void Main()
{
    // print the new value from the increment function
    Console.WriteLine(counter.Increment());
    // print off the value stored in the item
    Console.WriteLine(counter.Value);
}

The output of the program will be:

1
0

This seems completely wrong. I would either expect the output to be two 1s (as it is if Counter is a class or if struct Counter : ICounter and counter is an ICounter) or be a compilation error. I realize that detecting this at compilation time is a rather difficult matter, but this behavior seems to violate logic.

Is there a reason for this behavior beyond implementation difficulty?

+1  A: 

structs are value types and therefore have a value type sematics. This means each time you access the struct you basically work with a copy of the struct's value.

In your sample you don't change the original struct but only a temporary copy of it.

See here for further explanations:

Why are mutable structs evil

0xA3
But if you take away the `readonly`, then the expected output of two 1s happens. So it clearly does not make a copy in that instance. Does this mean that all functions called on readonly structs create copies of the struct (since C# has no concept of a mutating function)?
Travis Gockel
Yes, that is the case according to section 7.5.4 of the C# language specification. See Eric Lippert's post on the topic to get more details.
0xA3