Почему статические классы не могут иметь деструкторов? - PullRequest
13 голосов
/ 26 ноября 2009

Две части к этому:

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

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

Ответы [ 4 ]

19 голосов
/ 26 ноября 2009

Вместо статического класса вы должны использовать обычный класс с одноэлементным шаблоном (то есть вы сохраняете один единственный экземпляр класса, на который может ссылаться одно статическое свойство самого класса). Тогда вы можете иметь деструктор или, что еще лучше, комбинацию деструктора и метода 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();

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

7 голосов
/ 26 ноября 2009
  1. Статические классы не имеют деструкторов, потому что статический класс никогда не уничтожается.

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

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

3 голосов
/ 26 ноября 2009

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

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

1 голос
/ 26 ноября 2009

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

...