Comparaison entre classe, composant et contrôle

Cette rubrique définit un composant et un contrôle ; elle devrait vous aider à déterminer les cas dans lesquels implémenter une classe qui soit un composant ou un contrôle.

Notes

Cette rubrique traite des Windows Forms et des classes ASP.NET.Cette discussion ne s'applique pas aux classes WPF pour les informations relatives à la création de contrôles WPF, consultez Vue d'ensemble de la création de contrôles.

La liste suivante fournit des indications générales pour les implémenteurs.

  • Si votre classe utilise des ressources externes mais ne sera pas utilisée sur une aire de conception, implémentez IDisposable ou dérivez d'une classe qui implémente directement ou indirectement IDisposable.

  • Si votre classe doit être utilisée sur une aire de conception (telle que le concepteur Windows Forms ou Web Forms), implémentez IComponent ou dérivez d'une classe qui implémente directement ou indirectement IComponent. Notez que IComponent étend IDisposable, si bien qu'un type IComponent est toujours un type IDisposable. Un type IComponent présente une légère supériorité de performance sur un type IDisposable autre que IComponent, mais il est généralement décalé par la capacité d'installer IComponent au moment du design et de l'exécution. (L'installation est expliquée plus loin dans cette rubrique.)

  • Si vous souhaitez une classe qui soit concevable (à savoir utilisée sur une aire de conception) et marshalée par référence, vous pouvez dériver de Component. Component est l'implémentation de base d'un type IComponent qui est marshalé par référence.

  • Si vous souhaitez une classe concevable qui soit marshalée par valeur, vous pouvez dériver de MarshalByValueComponent. MarshalByValueComponent est l'implémentation de base d'un type IComponent qui est marshalé par valeur.

  • Si vous souhaitez introduire un type IComponent dans votre hiérarchie de modèle objet et que vous ne pouvez pas dériver d'une implémentation de base telle que Component ou MarshalByValueComponent à cause d'un seul héritage, implémentez IComponent.

  • Si vous souhaitez une classe concevable qui fournit une interface utilisateur, votre classe est un contrôle. Un contrôle doit dériver directement ou indirectement de l'une des classes de contrôle de base : Control ou Control.

    Notes

    Si votre classe n'est pas concevable et ne contient pas non plus de ressources externes, vous n'avez pas besoin d'un type IComponent ou IDisposable.

Vous trouverez plus loin les définitions de composant, contrôle, conteneur et site.

Composant

Dans le .NET Framework, un composant est une classe qui implémente l'interface IComponent ou qui dérive directement ou indirectement d'une classe qui implémente IComponent. En programmation, le terme composant est généralement utilisé pour désigner un objet qui est réutilisable et qui peut interagir avec d'autres objets. Un composant .NET Framework répond à ses exigences générales et propose d'autres fonctionnalités, telles que le contrôle des ressources externes et la prise en charge au moment du design.

Contrôle des ressources externes

L'interface IComponent étend l'interface IDisposable, qui possède une méthode nommée Dispose dans son contrat. Lors de son implémentation de la méthode Dispose, un composant doit explicitement libérer les ressources externes. Cela permet de libérer d'une manière déterministe les ressources, contrairement au nettoyage non déterministe par défaut qui se produit au cours d'une opération garbage collection. Les développeurs doivent propager Disposedans toute une hiérarchie de relation contenant-contenu pour garantir que les enfants d'un composant évitent également des ressources. De plus, un composant dérivé doit appeler la méthode Dispose de sa classe de base.

Notes

Même si vous assurez le contrôle explicite des ressources par le biais de Dispose, vous devez toujours assurer le nettoyage implicite par le biais du finaliseur (destructeur) pour éviter la fuite permanente des ressources lorsqu'un utilisateur ne parvient pas à appeler Dispose sur votre composant.

L'exemple suivant montre le mode d'implémentation de Dispose dans un composant de base et dans un composant dérivé.

public class BaseComponent : IComponent {

   // IComponent extends IDisposable.
   public void Dispose() {
        Dispose(true);
     GC.SuppressFinalize(this); 
      }

   protected virtual void Dispose(bool disposing) {
      if (disposing) {
          // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
   }

   // Simply call Dispose(false).
      ~BaseComponent(){
      Dispose (false);
   }
}
   
// Derived component.
public class DerivedComponent : BaseComponent {
   
   protected override void Dispose(bool disposing) {
      if (disposing) {
      // Free other state.
      }
      // You must invoke the Dispose method of the base class.
      base.Dispose(disposing);
      // Free your own state.
      ...
   }
   // No finalizer/destructor.
   // No Dispose() method.
}

   
' Design pattern for a base class.
Public Class BaseComponent
   Implements IComponent
   ' Implement IDisposable
   Public Overloads Sub Dispose() 
      Dispose(True)
      GC.SuppressFinalize(Me)
   End Sub

   Protected Overloads Overridable Sub Dispose(disposing As Boolean)
      If disposing Then
         ' Free other state (managed objects).
      End If
      ' Free your own state (unmanaged objects).
      ' Set large fields to null.
   End Sub

   Protected Overrides Sub Finalize()
      ' Simply call Dispose(False).
      Dispose (False)
   End Sub
End Class

' Design pattern for a derived component.
Public Class DerivedComponent
   Inherits BaseComponent

   Protected Overloads Overrides Sub Dispose(disposing As Boolean) 
      If disposing Then 
         ' Release managed resources.
      End If
      ' Release unmanaged resources.
      ' Set large fields to null.
      ' Call Dispose on your base class.
      Mybase.Dispose(disposing)
   End Sub
   ' The derived class does not have a Finalize method
   ' or a Dispose method with parameters because it inherits
   ' them from the base class.
End Class

Prise en charge au moment du design

Une fonctionnalité importante des composants dans le .NET Framework est le fait qu'ils sont concevables, ce qui signifie qu'une classe qui est un composant peut être utilisée dans un environnement RAD (Rapid Application Development), tel que Visual Studio. Un composant peut être ajouté à la boîte à outils de Visual Studio, faire l'objet d'un glisser-déplacer sur un formulaire et être manipulé sur une aire de conception. Notez que la prise en charge de base au moment du design pour les types IComponent est construite dans le .NET Framework ; un développeur de composant n'a aucun travail supplémentaire à effectuer pour profiter de la fonctionnalité de base au moment du design.

Pour plus d'informations sur la prise en charge au moment du design, consultez Attributs en mode design pour les composants et Extension de la prise en charge au moment du design.

Hébergement d'un composant

Un composant peut être installé (hébergé) dans un conteneur (défini ci-après dans cette rubrique). Lorsqu'un composant est installé, il interagit avec le conteneur via son site (défini ci-après dans cette rubrique) et est capable d'interroger et d'obtenir des services à partir de son conteneur via le site. Pour que les ressources soient libérées lors de la destruction d'un conteneur, un conteneur doit implémenter l'interface IDisposable. Lors de son implémentation de la méthode Dispose, un conteneur doit libérer toutes les ressources qu'il contient et appeler la méthode Dispose de chacun de ses composants contenus.

La relation contenant-contenu est logique et ne nécessite pas de représentation visuelle. Un conteneur de couche intermédiaire qui est installé dans des composants de base de données est un exemple de relation contenant-contenu non visuelle. La relation contenant-contenu visuelle est visible dans le Concepteur Windows Forms et le Concepteur Web Forms de Visual Studio. L'aire de conception visuelle est un conteneur qui héberge le composant de formulaire (dans Web Forms, le composant de page).

Marshaling d'un composant

Les composants peuvent être exécutables à distance ou non. Les composants exécutables à distance sont marshalés par référence ou par valeur. Le marshaling implique l'envoi d'objets au-delà de limites, telles que les Domaines d'application (processus légers), les processus et même les ordinateurs. Lorsqu'un objet est marshalé par référence, un proxy établissant des appels distants avec l'objet est créé. Lorsqu'un objet est marshalé par valeur, une copie sérialisée de l'objet est envoyée sur la limite appropriée.

Les composants exécutables à distance qui encapsulent les ressources système, qui sont volumineux ou qui existent sous la forme d'instances uniques, doivent être marshalés par référence. La classe de base des composants qui sont marshalés par référence est Component. Cette classe de base implémente IComponent et dérive de MarshalByRefObject. De nombreux composants de la bibliothèque de classes .NET Framework dérivent de Component, parmi lesquels Control (la classe de base des contrôles Windows Forms), WebService (la classe de base des services Web XML créés à l'aide de ASP.NET) et Timer (une classe qui génère des événements périodiques).

Les composants exécutables à distance qui contiennent simplement l'état doivent être marshalés par valeur. La classe de base des composants qui sont marshalés par valeur est MarshalByValueComponent. Cette classe de base implémente IComponent et dérive de Object. Seuls quelques composants de la bibliothèque de classes .NET Framework dérivent de MarshalByValueComponent. Tous ces composants se trouvent dans l'espace de noms System.Data (DataColumn, DataSet, DataTable, DataView et DataViewManager).

Notes

Les classes de base des objets qui sont marshalés par valeur et par référence sont respectivement Object et MarshalByRefObject, mais les classes dérivées correspondantes sont nommées MarshalByValueComponent et Component.La logique selon laquelle le type le plus fréquemment utilisé possède le nom le plus simple repose à la base du schéma d'affectation de noms.

Si un composant n'est pas exécuté à distance, ne dérivez pas à partir des implémentations de base de Component ; implémentez plutôt IComponent directement.

Contrôle

Un contrôle est un composant qui propose (ou active) des fonctionnalités d'interface utilisateur. Le .NET Framework fournit deux classes de base pour les contrôles : une pour les contrôles Windows Forms côté client et une pour les contrôles serveur ASP.NET. Il s'agit de Control et de Control. Tous les contrôles de la bibliothèque de classes du .NET Framework dérivent directement ou indirectement de ces deux classes. Control dérive de Component et fournit lui-même des fonctions d'interface utilisateur. Control implémente IComponent et fournit l'infrastructure sur laquelle il est facile d'ajouter des fonctionnalités d'interface utilisateur.

Notes

Chaque contrôle est un composant, mais l'inverse n'est pas exact.

Conteneur et site

Si vous développez des composants et des contrôles pour Windows Forms ou pour des pages Web Forms (pages ASP.NET), vous n'avez pas à implémenter de conteneurs ni de sites. Les concepteurs pour Windows Forms et pour Web Forms sont des conteneurs pour Windows Forms et pour des contrôles serveur ASP.NET. Les conteneurs proposent des services aux composants et aux contrôles qui y sont installés. Au moment du design, les contrôles sont installés dans le concepteur et obtiennent des services à partir du concepteur. À des fins de précision, les définitions d'un conteneur et d'un site sont données ci-dessous.

  • Container
    Un conteneur est une classe qui implémente l'interface IContainer ou dérive d'une classe qui implémente cette interface. Un conteneur contient logiquement un ou plusieurs composants qui sont appelés les composants enfants du conteneur.

  • Site
    Un site est une classe qui implémente l'interface ISite ou dérive d'une classe qui implémente cette interface. Les sites sont fournis par un conteneur pour manager ses composants enfants et communiquer avec eux. En général, un conteneur et un site sont implémentés sous la forme d'une unité.

Voir aussi

Concepts

Vue d'ensemble des propriétés

Attributs en mode design pour les composants

Autres ressources

Développement de contrôles Windows Forms personnalisés avec le .NET Framework

Developing Custom ASP.NET Server Controls

Extension de la prise en charge au moment du design