2009-11-26 13 views
13

deux parties: cePourquoi les classes statiques ne peuvent-elles pas avoir de destructeurs?

  1. Si une classe statique peut avoir un constructeur statique, pourquoi ne peut-il avoir une destructor statique?

  2. 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 soient fermées/libérées si quelque chose explose ailleurs dans le programme.

Répondre

18

Au lieu d'une classe statique, vous devriez utiliser une classe normale avec le modèle singleton (c'est-à-dire, vous gardez une seule instance de la classe, peut-être référencée par une propriété statique sur la classe elle-même). Ensuite, vous pouvez avoir un destructeur, ou mieux, une combinaison de destructeur et Dispose méthode.

Par exemple, si vous avez maintenant:

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

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

vous auriez à la place:

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

(Remarquez comment l'instance est créée dans le constructeur statique, qui est invoqué pour la première fois l'un des membres statiques de la classe est référencé)

+1

Merci. J'ai également ajouté à mon code un constructeur privé non statique afin que la classe ne puisse pas être instanciée ailleurs. –

+0

Si le thread doit être utilisé, vous devez rendre le code thread-safe. –

+1

Il y a un bon guide ici sur toutes les différentes façons de faire le motif Singleton avec la sécurité du fil. http://csharpindepth.com/Articles/General/Singleton.aspx – Naz

3

1. Pourquoi? - Un type ne peut pas avoir de constructeur en soi comme dans la façon dont vous pensez habituellement des constructeurs sur les instances. En général, il est parfois connu comme une méthode "initialiseur statique" mais Microsoft utilise la terminologie "type constructeur" (et il a des restrictions spéciales) - vous mettez du code pour init le type/classe - si c'était un constructeur d'instance, il pourrait être surchargé. Cette restriction statique sur "constructeur de type" est due au fait que .NET CLR est chargé de charger le modèle de classe sur le tas et ne permet pas de spécifier les paramètres dans cette circonstance (car comment transmettriez-vous des arguments). Parce que, dans le sens le plus strict, le programmeur n'est pas responsable de l'invocation du constructeur de type, cela n'aurait pas beaucoup de sens de permettre au programmeur de coder un destructeur statique quand il est plus dans le domaine du CLR. Le CLR supprimera éventuellement le modèle de classe du tas, mais la durée de vie du modèle de classe est plus longue que ses instances, donc vous ne voudriez pas faire quoi que ce soit en ressources (par exemple, maintenez une connexion db ouverte).

2. Quoi? - Singleton Si vous rencontrez une situation dans laquelle vous estimez devoir ouvrir une ressource sur le modèle de classe et la détruire par la suite, vous pouvez considérer le Singleton software pattern comme ayant une seule instance de cette classe et éventuellement implémenter l'interface System.IDiposable aider avec le nettoyage, en plus du destructeur. (Je vois quelqu'un m'a déjà battu à l'échantillon de code IDisposable d'abord, donc je vais terminer ma solution ici.)

7
  1. Les classes statiques n'ont pas de destructeurs car une classe statique n'est jamais détruite.

  2. Si vous souhaitez créer et détruire plusieurs instances, il ne doit pas être statique. Faites-en un cours complet.

  3. De toute façon, les destructeurs ne doivent pas être utilisés à cette fin. Utilisez IDisposable/Dispose.

+0

Pourquoi le compilateur vous permet-il d'en avoir un? 'static ~ ClassName() {}' est-ce que ça ne fonctionne jamais? – Zapnologica

1

Une classe statique n'est jamais détruite. Il est terminé avec le programme. Vous pouvez utiliser le motif singleton comme implémentation au lieu d'utiliser une classe statique.

+0

Etes-vous sûr qu'un Class (-type) n'est pas collecté? –

+0

@HenkHolterman Oui. Il n'y a rien à collectionner. Puisque toutes les propriétés/champs ont au moins une référence (la classe statique) et que la portée de la classe statique est du premier accès jusqu'à ce que le programme soit terminé, il n'y a rien à collecter –