2

Leaving aside whether it's a horrendous terrible idea to ever implement IDisposable on a non-reference type, would the Dispose() method get called when a non-reference IDisposable is removed from the stack?

Alex Krupka
  • 710
  • 9
  • 20
  • Nope i mean IDisposable.Dispose – Alex Krupka May 05 '16 at 12:55
  • 2
    Why on earth you want IDisposable struct? – Hamid Pourjam May 05 '16 at 12:57
  • Canonical link: https://ericlippert.com/2011/03/14/to-box-or-not-to-box/ – stuartd May 05 '16 at 12:58
  • 4
    @dotctor For the exact same reasons you'd want a disposable reference type. It has unmanaged resources to clean up. – Servy May 05 '16 at 12:58
  • I'm aware of the boxing problem i'm not dealing with an unmanaged resource. Using more for cleaning non used (cached) dictionary items – Alex Krupka May 05 '16 at 13:03
  • 2
    @AlexKrupka If you have references inside of your `struct` it should probably be a class instead. If you don't have unmanaged resources, or a reference to an `IDisposable` type then you don't need to make your struct/class disposable in the first place. – juharr May 05 '16 at 13:06
  • I'm implementing a lock generation class that provides a object to lock-on based on the requested key. In order to keep the dictionary from getting too large I need a way of keeping track of what threads have refs to the object I'm using a struct to wrap the object so that on its dispose it removes its "ref" (stored in keyvaluepair>) to the object and if there are no other refs removes from dictionary (concurrent - with locking to make sure no adds to hashset) – Alex Krupka May 05 '16 at 13:13
  • I should add that its not the end of the world if the object remains in the dictionary this is just to keep memory allocation down – Alex Krupka May 05 '16 at 13:18
  • 1
    @AlexKrupka Then you're doing the wrong thing. You're spending more memory trying to save memory than you'd spend creating the objects when you need them. – Servy May 05 '16 at 13:28
  • @Servy No. There are potentially an infinite amount of keys that can be called only a limited amount of threads to do the calling – Alex Krupka May 05 '16 at 13:31
  • 1
    @AlexKrupka That doesn't change the fact that you're better off just re-creating objects when you need them than trying to keep them around for re-use. – Servy May 05 '16 at 13:46
  • @Servy my bad for not explaining properly. The object is being used for the locking. Each key needs its own lock so i need a way for dif thread to lock if they are updating the same key. So i need persistence of objects as long as any thread is ref it – Alex Krupka May 05 '16 at 13:50

1 Answers1

3

The answer is: NO,

Merely creating a struct that lives on the stack will NOT cause Dispose() to be called when it goes out of scope. (Of course, neither will that happen for a class.)

Dispose() will only be called if it is called explicitly, or if it is called implicitly through a using.

However, Dispose() will be called if a struct implements IDisposable and is used inside a using, like so:

using System;

namespace Demo
{
    struct Test: IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("Help! Help! I'm being oppressed!");
        }
    }
    static class Program
    {
        static void Main()
        {
            using (var test = new Test())
            {
                Console.WriteLine("Using a Test object");
            }
        }
    }
}

This outputs

Using a Test object
Help! Help! I'm being oppressed!

Note that structs are generally intended to be lightweight, and shouldn't really contain references (except perhaps for strings). In that case, a struct shouldn't have anything disposable in it, so this question wouldn't arise.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276