Почему статические классы не могут иметь деструкторы?

Две части:

  • Если статический класс может иметь статический конструктор, почему он не может иметь статический деструктор?

  • Какое лучшее обходное решение? У меня есть статический класс, который управляет пулом соединений, которые являются объектами COM, и мне нужно убедиться, что их соединения закрываются/освобождаются, если что-то взрывается в другом месте программы.

Ответы

Ответ 1

Вместо статического класса вы должны использовать обычный класс с шаблоном singleton (т.е. вы сохраняете один экземпляр класса, возможно, ссылаясь на одно статическое свойство самого класса). Тогда у вас может быть деструктор или, что еще лучше, комбинация деструктора и Dispose.

Например, если у вас есть:

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

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

вместо этого вы должны:

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();

(Обратите внимание, как экземпляр создается в статическом конструкторе, который вызывается при первом обращении к любому из статических членов класса)

Ответ 2

  • Статические классы не имеют деструкторов, потому что статический класс никогда не уничтожается.

  • Если вы хотите создать и уничтожить несколько экземпляров, он не должен быть статическим. Сделайте это полноценным классом.

  • Деструкторы не должны использоваться для этой цели в любом случае. Используйте IDisposable/Dispose.

Ответ 3

1. Зачем? - Тип не может иметь конструктора как такового, как в том, как вы обычно думаете о конструкторах на экземплярах. В общем, это иногда называют "статическим инициализатором", но Microsoft использует терминологический "конструктор типов" (и имеет особые ограничения) - вы вставляете в него код для инициализации типа/класса - если это был конструктор экземпляра, он мог бы быть перегружен. Это статическое ограничение на "конструктор типов" связано с тем, что .NET CLR отвечает за загрузку шаблона класса в кучу и не позволяет указывать параметры в этом случае (потому что как бы вы когда-либо проходили аргументы). Поскольку в строгом смысле программист не несет ответственности за то, чтобы вызвать конструктор типа, он не имеет смысла позволять программисту кодировать статический деструктор, когда он больше в домене CLR. CLR в конечном итоге удалит шаблон класса из кучи, но срок жизни шаблона класса больше, чем его экземпляры, поэтому вы все равно не хотите делать что-либо ресурсоемким в нем (например, держите открытое соединение db).

2. Какие? - Singleton Если вы столкнулись с ситуацией, когда вы чувствуете, что вам нужно открыть ресурс в шаблоне класса и впоследствии уничтожить его, вы можете рассмотреть шаблон программного обеспечения Singleton иметь только один экземпляр этого класса и, возможно, также реализовать интерфейс System.IDiposable, чтобы помочь с очисткой в ​​дополнение к деструктору. (Я вижу, что кто-то уже избил меня до образца IDisposable, поэтому я закончу свое решение здесь.)

Ответ 4

Статический класс никогда не уничтожается. Он завершился вместе с программой. Вы можете использовать шаблон singleton в качестве реализации вместо использования статического класса