Pourquoi les classes statiques ne peuvent-elles pas avoir de destructeurs?
-
05-07-2019 - |
Question
Deux parties à ceci:
-
Si une classe statique peut avoir un constructeur statique, pourquoi ne peut-elle pas avoir un destructeur statique?
-
Quelle est la meilleure solution de contournement? J'ai une classe statique qui gère un pool de connexions qui sont des objets COM et je dois m'assurer que leurs connexions sont fermées / libérées si quelque chose explose ailleurs dans le programme.
La solution
Au lieu d’une classe statique, vous devriez utiliser une classe normale avec le modèle singleton (c’est-à-dire que vous gardez une seule instance de la classe, éventuellement référencée par une propriété statique de la classe elle-même). Ensuite, vous pouvez avoir un destructeur, ou mieux encore, une combinaison de destructeur et de Supprimer méthode.
Par exemple, si vous avez maintenant:
static class MyClass
{
public static void MyMethod() {...}
}
//Using the class:
MyClass.MyMethod();
vous auriez plutôt:
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();
(Notez comment l'instance est créée dans le constructeur statique, qui est invoqué la première fois qu'un des membres statiques de la classe est référencé)
Autres conseils
-
Les classes statiques n'ont pas de destructeurs car une classe statique n'est jamais détruite.
-
Si vous voulez en créer et en détruire plusieurs instances, cela ne devrait pas être statique. Faites-en une classe complète.
-
Les destructeurs ne devraient de toute façon pas être utilisés à cette fin. Utilisez IDisposable / Dispose.
1. Pourquoi? - Un type ne peut pas avoir de constructeur en soi, contrairement à ce que vous pensez habituellement des constructeurs sur les instances. En général, il est parfois appelé "initialiseur statique". méthode mais Microsoft utilise la terminologie "constructeur du type" (et il a des restrictions spéciales) - vous y mettez du code pour initier le type / la classe - s'il s'agissait d'un constructeur d'instance, il pourrait être surchargé. Cette restriction statique sur le "constructeur de type" " Cela est dû au fait que .NET CLR est responsable du chargement du modèle de classe sur le tas et qu’il ne permet pas de spécifier des paramètres dans ce cas (car comment passeriez-vous des arguments). Parce que, dans le sens le plus strict, le programmeur n’est pas responsable de l’appel du constructeur de type, il n’a pas de sens de lui permettre de coder un destructeur statique quand il est davantage dans le domaine du CLR. Le CLR supprimera éventuellement le modèle de classe du segment de mémoire, mais sa durée de vie est plus longue que ses instances. Vous ne voudrez donc pas utiliser de ressources gourmandes en ressources (par exemple, maintenir ouverte une connexion à une base de données).
2. Quelle? - Singleton Si vous pensez que vous devez ouvrir une ressource sur le modèle de classe et le détruire par la suite, vous pouvez envisager le Modèle logiciel Singleton pour n'avoir qu'une seule instance de cette classe et éventuellement implémenter également le System.IDiposable interface facilitant le nettoyage, en plus du destructeur. (Je vois que quelqu'un m'a déjà battu à l'exemple de code IDisposable en premier, alors je vais terminer ma solution ici.)
Une classe statique n'est jamais détruite. Il est terminé avec le programme. Vous pouvez utiliser le modèle singleton en tant qu’implémentation au lieu d’utiliser une classe statique