2014-05-07 4 views
0

J'ai créé une fabrique DAO générique. La classe factory implémente IDisposable.Destructeurs en classe générique

Je veux créer un destructeur pour cette classe générique, afin qu'il implémente IDisposable correctement. Comment puis-je définir destructor pour cette classe générique?

Est-ce même nécessaire ou devrais-je laisser l'implémentation de IDispoable et destructor à ses classes de base non génériques?

+1

Êtes-vous sûr que vous avez réellement besoin d'un destructor/finaliseur? – sloth

+1

Je ne comprends pas la question: vous pouvez définir un destructeur comme vous le feriez pour une classe non générique, et ce que vous * devriez * faire est une question de conception. – Jon

+0

@Jon. Merci pour votre réponse. Ça a marché. Dominic, cette classe implémente IDisposable donc à mon avis les destructeurs/finalizer devraient être là. – Sandeep

Répondre

1

Il sont quelques clés sur du livre MCSD Toolkit de certification (examen 70-483) pag 193:

destructor ≈ (il est presque égal à) base.Finalize(), Le destructor est converti en une version de substitution de la méthode Finalize qui exécute le code du destructeur, puis appelle la méthode Finalize de la classe de base. Ensuite, il est totalement non déterministe, vous ne pouvez pas savoir quand il sera appelé parce que cela dépend de GC.

Si une classe ne contient pas de ressources gérées et aucune ressource non gérés, il n'a pas besoin de mettre en œuvre IDisposableor ont un destructor.

Si la classe n'a réussi ressources, il faut mettre en œuvre IDisposable, mais il n'a pas besoin d'un destructor. (Lorsque le destructor exécute, vous ne pouvez pas être sûr des objets gérés encore existent, de sorte que vous ne pouvez pas appeler leurs Disposemethods de toute façon.)

Si la classe ne dispose que de ressources non gérées, il a besoin de mettre en œuvre IDisposableand a besoin d'un destructeur au cas où le programme n'appelle pas Dispose.

La méthode Dispose doit pouvoir s'exécuter plusieurs fois en toute sécurité. Vous pouvez y parvenir en utilisant une variable pour savoir si elle a déjà été exécutée.

La méthode Dispose doit libérer les ressources gérées et non gérées.

Le destructeur ne doit libérer que des ressources non gérées. (Lorsque les exécute destructor, vous ne peut pas être sûr que les objets gérés existent toujours, de sorte que vous ne pouvez pas appeler leurs Disposemethods de toute façon.)

Après avoir libéré les ressources, l'destructor doivent appeler GC.SuppressFinalize, de sorte que l'objet pouvez ignorer la file d'attente de finalisation.

Un exemple de mise en œuvre d'une pour une classe avec des ressources non gérées et gérées:

using System; 

class DisposableClass : IDisposable 
{ 
    // A name to keep track of the object. 
    public string Name = ""; 

    // Free managed and unmanaged resources. 
    public void Dispose() 
    { 

     FreeResources(true); 
    } 

    // Destructor to clean up unmanaged resources 
    // but not managed resources. 
    ~DisposableClass() 
    { 
     FreeResources(false); 
    } 

    // Keep track if whether resources are already freed. 
    private bool ResourcesAreFreed = false; 

    // Free resources. 
    private void FreeResources(bool freeManagedResources) 
    { 
     Console.WriteLine(Name + ": FreeResources"); 
     if (!ResourcesAreFreed) 
     { 
      // Dispose of managed resources if appropriate. 
      if (freeManagedResources) 
      { 
       // Dispose of managed resources here. 
       Console.WriteLine(Name + ": Dispose of managed resources"); 
      } 

      // Dispose of unmanaged resources here. 
      Console.WriteLine(Name + ": Dispose of unmanaged resources"); 

      // Remember that we have disposed of resources. 
      ResourcesAreFreed = true; 

      // We don't need the destructor because 
      // our resources are already freed. 
      GC.SuppressFinalize(this); 
     } 
    } 
} 
Questions connexes