I discovered that iterator methods in value types are allowed to modify this.
However, due to limitations in the CLR, the modifications are not seen by the calling method.  (this is passed by value)
Therefore, identical code in an iterator and a non-iterator produce different results:
static void Main() {
    Mutable m1 = new Mutable();
    m1.MutateWrong().ToArray();     //Force the iterator to execute
    Console.WriteLine("After MutateWrong(): " + m1.Value);
    Console.WriteLine();
    Mutable m2 = new Mutable();
    m2.MutateRight();
    Console.WriteLine("After MutateRight(): " + m2.Value);
}
struct Mutable {
    public int Value;
    public IEnumerable<int> MutateWrong() {
        Value = 7;
        Console.WriteLine("Inside MutateWrong(): " + Value);
        yield break;
    }
    public IEnumerable<int> MutateRight() {
        Value = 7;
        Console.WriteLine("Inside MutateRight(): " + Value);
        return new int[0];
    }
}
Output:
Inside MutateWrong(): 7 After MutateWrong(): 0 Inside MutateRight(): 7 After MutateRight(): 7
Why isn't it a compiler error (or at least warning) to mutate a struct in an iterator?
This behavior is a subtle trap which is not easily understood.
Anonymous methods, which share the same limitation, cannot use this at all.
Note: mutable structs are evil; this should never come up in practice.
 
     
     
     
     
     
    