Почему статические классы не могут иметь деструкторы?
Две части:
-
Если статический класс может иметь статический конструктор, почему он не может иметь статический деструктор?
-
Какое лучшее обходное решение? У меня есть статический класс, который управляет пулом соединений, которые являются объектами 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 в качестве реализации вместо использования статического класса