views:

312

answers:

4

Two parts to this:

  1. If a static class can have a static constructor, why can't it have a static destructor?

  2. What is the best workaround? I have a static class that manages a pool of connections that are COM objects, and I need to make sure their connections get closed/released if something blows up elsewhere in the program.

+2  A: 

1. Why? -- A type cannot have a constructor per se as in how you usually think of constructors on instances. In general it's sometimes known as a "static initializer" method but Microsoft uses the terminology "type constructor" (and it has special restrictions) - you put code in it to init the type/class - if it was an instance constructor it could be overloaded. This static restriction on "type constructor" is because .NET CLR is responsible for loading the class template on the heap and doesn't allow parameters to be specified under this circumstance (because how would you ever pass arguments). Because in the strictest sense the programmer is not responsible for causing the type constructor to be invoked, it wouldn't make much sense to allow the programmer to code a static destructor when it's more in the CLR's domain. The CLR will eventually remove the class template from the heap, but the class template's lifetime is longer than its instances, so you wouldn't want to do anything resource intensive in it anyway (e.g. hold open a db connection).

2. What? - Singleton If you are running into a circumstance where you feel you need to open a resource on the class template and destroy it afterward, you might consider the Singleton software pattern to have only one instance of that class and possibly also implement the System.IDiposable interface to aid with cleanup, in addition to the destructor. (I see somebody has already beaten me to the IDisposable code sample first, so I will end my solution here.)

John K
+11  A: 

Instead of a static class, you should use a normal class with the singleton pattern (that is, you keep one single instance of the class, perhaps referenced by one static property on the class itself). Then you can have a destructor, or even better, a combination of destructor and Dispose method.

For example, if you now have:

static class MyClass
{
    public static void MyMethod() {...}
}

//Using the class:
MyClass.MyMethod();

you would have instead:

class MyClass : IDisposable
{
    public static MyClass()
    {
        Instance=new MyClass();
    }

    public static MyClass Instance {get; private set;}

    public void MyMethod() {...}

    public void Dispose()
    {
        //...
    }

    ~MyClass()
    {
        //Your destructor goes here
    }
}

//Using the class:
MyClass.Instance.MyMethod();

(Notice how the instance is created in the static constructor, which is invoked the first time that any of the class static members is referenced)

Konamiman
Thank you. I have also added to my code a private non-static constructor so the class can't be instantiated elsewhere.
Jon Seigel
If threading will be used, need to make code thread-safe.
Roman Boiko
+3  A: 
  1. Static classes don't have destructors because a static class never gets destroyed.

  2. If you want to create and destroy multiple instances of it, it shouldn't be static. Make it a full class.

  3. Destructors shouldn't be used for this purpose anyway. Use IDisposable / Dispose.

Mark Byers
A: 

A static class is never destroyed. It's terminated together with the program. You could use the singleton pattern as an implemenation instead of using a static class

Rune FS
Are you sure a Class(-type) is not garbage collected?
Henk Holterman