2

Found some weird behevior with c# struct and using statement. Not sure why this is happening. Sample struct:

public struct Thing : IDisposable {
    private bool _dispose;

    public void Dispose() {
        _dispose = true;
    }
    public bool GetDispose() {
        return _dispose;
    }
    public void SetDispose(bool dispose) {
        _dispose = dispose;
    }
}

And usage of this struct:

        var thing = new Thing();
        using (thing) {
            Console.WriteLine(thing.GetDispose());
        }
        Console.WriteLine(thing.GetDispose());

I expect here to see the following output:

False
True

Because Dispose() method is called at the end of using scope. But I get:

False
False

If I change struct to class, or use struct and add thing.SetDispose(true); inside using scope, I get expected output

False
True

My question is why do I get False False with a struct? I checked with debugger, Dispose() is called every time at the end of using scope.

Vasyl Chuy
  • 31
  • 3
  • would be interesting to see the generated IL – pm100 Jun 16 '20 at 04:28
  • @pm100 [Here you go](https://sharplab.io/#v2:C4LglgNgPgAgTARgLACgYGYAE9MGFMDeqmJ2WMALJgLIAUAlIcaSwG4CGATpsABZgA7AOaYAvJgEBTAO6YAKv2EMA3MxYkYABky0+goYyIp1J7AgCcuxUIB0AcUnAAImADOABwD2ryQ3qrjUwBfNXUYCyt9e0cXD29fen9QkJQU1AxMV2BOAFcAY2B5a0wQTABJWK9XdgAjCEkmQJJ3TjAOYAaaz08ITAB9ABM3KskA0IzKTEr4hkbTfqG4nzEeXNHk8awunswHZ2GZw1CWGAB2BYOfAJYUk/IqAGUYy99t3sWRo6b1QZeVj/i11IKSCQA==) – ProgrammingLlama Jun 16 '20 at 04:30
  • 1
    v odd, subtle code change when struct -> class . paging mr skeet – pm100 Jun 16 '20 at 04:35
  • Why not using a property for "_dispose"? – Adrian Efford Jun 16 '20 at 04:45

1 Answers1

4

The structs are value types, so in this piece of code, the original struct will be copied to a new one inside using statement.

Your code at the end will be translated to:

var thing = new Thing();                     //thing._dispose == false
using (Thing thing2 = thing) {               //thing2.dispose == false   
     Console.WriteLine(thing2.GetDispose()); //thing2.dispose == false
}                                            //thing2.dispose == true
                                             //BUT thing1.dispose == false
Console.WriteLine(thing.GetDispose());

You can read more here: https://ericlippert.com/2011/03/14/to-box-or-not-to-box/

Grigory Zhadko
  • 1,484
  • 1
  • 19
  • 33