648 votes

Quand utiliser les classes statiques en C#

Voici ce que MSDN a à dire sous Quand utiliser les classes statiques :

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
    //...
}

Utiliser une classe statique comme unité d'organisation d'organisation pour les méthodes non associées à des objets particuliers. De plus, une classe statique peut rendre votre implémentation plus simple et plus rapide car vous n'avez pas besoin de créer un objet afin d'appeler ses méthodes. Il est utile d'organiser les méthodes à l'intérieur de la classe d'une manière significative, comme les méthodes de la classe Math dans l'espace de nom System.

Pour moi, cet exemple ne semble pas couvrir un grand nombre de scénarios d'utilisation des classes statiques. Dans le passé, j'ai utilisé des classes statiques pour des suites de fonctions connexes sans état, mais c'est à peu près tout. Alors, dans quelles circonstances une classe doit-elle (ou ne doit-elle pas) être déclarée statique ?

19 votes

En tant que débutant en C#, il serait utile d'expliquer pourquoi cette question a été marquée comme faisant double emploi avec la question de l'année précédente. singleton et classe statique et comment les deux sont liés l'un à l'autre.

1 votes

mr5, singleton et classe statique sont fondamentalement la même chose. Singleton est un modèle de conception utilisé dans d'autres langages pour simuler une classe statique, puisque d'autres langages (comme Java) n'ont pas de classes statiques intégrées, vous devez donc compter sur le modèle de conception Singleton pour créer une telle classe. La classe statique est une classe qui ne peut pas être instanciée et qui peut être utilisée directement (comme la classe Console par exemple). tutorialspoint.com/design_pattern/singleton_pattern.htm si vous vérifiez cela, vous verrez que lorsque vous utilisez le Singleton, vous ne créez pas une nouvelle instance...

0 votes

... vous utilisez celui qui a déjà été créé dans la classe Singleton, et vous y accédez par la méthode .getInstance(). Le C# résout tout cela par un simple mot-clé "static".

759voto

Mark S. Rasmussen Points 13313

J'ai écrit mes réflexions sur les classes statiques dans une réponse antérieure à Stack Overflow : Classe avec une seule méthode - meilleure approche ?

J'adorais les classes utilitaires remplies de méthodes statiques. Elles permettaient de consolider les méthodes d'aide qui, autrement, auraient été inutilisées, ce qui aurait entraîné une redondance et une maintenance infernale. Elles sont très faciles à utiliser, pas d'instanciation, pas d'élimination, il suffit de les lancer et de les oublier. Je suppose que c'était ma première tentative involontaire de créer une architecture orientée service - beaucoup de services sans état qui faisaient juste leur travail et rien d'autre. Cependant, au fur et à mesure qu'un système se développe, les dragons arrivent.

Polymorphisme

Supposons que nous ayons la méthode UtilityClass.SomeMethod qui se porte bien. Soudain, nous avons besoin de modifier légèrement sa fonctionnalité. La plupart des fonctionnalités sont les mêmes, mais nous devons tout de même en modifier quelques parties. S'il ne s'agissait pas d'une méthode statique, nous pourrions créer une classe dérivée et modifier le contenu de la méthode selon les besoins. Comme il s'agit d'une méthode statique, nous ne pouvons pas le faire. Bien sûr, si nous avons juste besoin d'ajouter une fonctionnalité avant ou après l'ancienne méthode, nous pouvons créer une nouvelle classe et appeler l'ancienne à l'intérieur de celle-ci - mais c'est juste grossier.

Les problèmes d'interface

Les méthodes statiques ne peuvent pas être définies par le biais d'interfaces pour des raisons logiques. Et puisque nous ne pouvons pas surcharger les méthodes statiques, les classes statiques sont inutiles lorsque nous avons besoin de les faire circuler par leur interface. Il est donc impossible d'utiliser les classes statiques dans le cadre d'un modèle de stratégie. Nous pouvons résoudre certains problèmes en passer des délégués au lieu d'interfaces .

Essais

Cela va de pair avec les problèmes d'interface mentionnés ci-dessus. Comme notre capacité à interchanger les implémentations est très limitée, nous aurons également du mal à remplacer le code de production par du code de test. Encore une fois, nous pouvons les envelopper, mais cela nous obligera à modifier de grandes parties de notre code juste pour pouvoir accepter les enveloppes au lieu des objets réels.

Fosters blobs

Comme les méthodes statiques sont généralement utilisées comme des méthodes utilitaires et que les méthodes utilitaires ont généralement des objectifs différents, nous nous retrouverons rapidement avec une grande classe remplie de fonctionnalités non cohérentes - idéalement, chaque classe devrait avoir un objectif unique au sein du système. Je préférerais avoir cinq fois plus de classes, tant que leurs objectifs sont bien définis.

Fluctuation des paramètres

Au début, cette petite méthode statique mignonne et innocente peut prendre un seul paramètre. Au fur et à mesure que la fonctionnalité se développe, quelques nouveaux paramètres sont ajoutés. Bientôt, d'autres paramètres facultatifs sont ajoutés, et nous créons donc des surcharges de la méthode (ou ajoutons simplement des valeurs par défaut, dans les langages qui les prennent en charge). Très vite, nous avons une méthode qui prend 10 paramètres. Seuls les trois premiers sont réellement requis, les paramètres 4 à 7 sont facultatifs. Mais si le paramètre 6 est spécifié, les paramètres 7 à 9 doivent également être renseignés... Si nous avions créé une classe dans le seul but de faire ce que cette méthode statique fait, nous pourrions résoudre ce problème en prenant les paramètres requis dans le constructeur, et en permettant à l'utilisateur de définir des valeurs optionnelles par le biais de propriétés, ou de méthodes pour définir plusieurs valeurs interdépendantes en même temps. De plus, si une méthode a atteint un tel niveau de complexité, elle doit très probablement faire partie de sa propre classe.

Demander aux consommateurs de créer une instance de classe sans raison valable

L'un des arguments les plus courants est le suivant : Pourquoi demander aux consommateurs de notre classe de créer une instance pour invoquer cette seule méthode, alors qu'ils n'ont aucune utilité de cette instance par la suite ? La création d'une instance d'une classe est une opération très très bon marché dans la plupart des langages, la vitesse n'est donc pas un problème. Ajouter une ligne de code supplémentaire au consommateur est un faible coût pour poser les bases d'une solution beaucoup plus facile à maintenir à l'avenir. Enfin, si vous voulez éviter de créer des instances, il suffit de créer un wrapper singleton de votre classe qui permet une réutilisation facile - bien que cela exige que votre classe soit sans état. Si elle n'est pas apatride, vous pouvez toujours créer des méthodes de wrapper statiques qui gèrent tout, tout en vous donnant tous les avantages à long terme. Enfin, vous pouvez également créer une classe qui masque l'instanciation comme s'il s'agissait d'un singleton : MyWrapper.Instance est une propriété qui retourne simplement new MyClass();

Seul un Sith traite avec des absolus.

Bien sûr, il y a des exceptions à mon aversion pour les méthodes statiques. Les véritables classes utilitaires qui ne présentent aucun risque de gonflement sont d'excellents cas pour les méthodes statiques - System.Convert par exemple. Si votre projet est unique et ne nécessite pas de maintenance future, l'architecture globale n'est pas vraiment importante - statique ou non statique, cela n'a pas vraiment d'importance - mais la vitesse de développement, si.

Les normes, les normes, les normes !

L'utilisation de méthodes d'instance ne vous empêche pas d'utiliser également des méthodes statiques, et vice versa. Tant qu'il y a un raisonnement derrière la différenciation et que celle-ci est standardisée. Il n'y a rien de pire que de regarder une couche d'entreprise qui s'étale avec différentes méthodes de mise en œuvre.

12 votes

Steve Yegge a également écrit sur le sujet. Mais son article est beaucoup plus long qu'il ne peut l'être ici. Si vous n'êtes toujours pas convaincu, essayez steve.yegge.googlepages.com/singleton-considéré-stupide

322 votes

Est-ce que quelqu'un a déjà remarqué que la phrase "Seul un Sith fait dans l'absolu" est un absolu ? Désolé. Je n'ai pas pu m'en empêcher.

4 votes

Tout comme je prends des risques pour faire passer mon point de vue, Yegge fait de même. Certains de ses arguments se résument à des considérations de programmation normale - si le singleton garde des ressources précieuses ouvertes, cela peut être un problème, bien sûr. Si l'on y réfléchit bien, les singletons et les statiques ont leur place.

160voto

Despertar Points 5365

Lorsque vous décidez de rendre une classe statique ou non statique, vous devez examiner les informations que vous essayez de représenter. Cela implique une approche plus ' ascendant Un style de programmation où l'on se concentre d'abord sur les données que l'on représente. La classe que vous écrivez est-elle un objet du monde réel, comme une pierre ou une chaise ? Ces objets sont physiques et ont des attributs physiques tels que la couleur, le poids, ce qui vous indique que vous pouvez vouloir instancier plusieurs objets avec des propriétés différentes. Je peux vouloir une chaise noire ET une chaise rouge en même temps. Si vous avez besoin de deux configurations en même temps, vous savez immédiatement que vous voudrez l'instancier en tant qu'objet afin que chaque objet soit unique et existe en même temps.

D'autre part, les fonctions statiques se prêtent davantage aux actions qui n'appartiennent pas à un objet du monde réel ou à un objet que vous pouvez facilement représenter. Rappelez-vous que les prédécesseurs de C# sont C++ et C, où vous pouvez simplement définir des fonctions globales qui n'existent pas dans une classe. Cela se prête davantage à ' de haut en bas programmation. Les méthodes statiques peuvent être utilisées dans les cas où il n'est pas logique qu'un "objet" effectue la tâche. En vous obligeant à utiliser des classes, cela facilite le regroupement de fonctionnalités connexes, ce qui vous aide à créer un code plus facile à maintenir.

La plupart des classes peuvent être représentées par des classes statiques ou non statiques, mais en cas de doute, revenez à vos racines de la POO et essayez de réfléchir à ce que vous représentez. S'agit-il d'un objet qui effectue une action (une voiture qui peut accélérer, ralentir, tourner) ou de quelque chose de plus abstrait (comme l'affichage d'une sortie).

Entrez en contact avec l'OOP qui sommeille en vous et vous ne pourrez jamais vous tromper !

15 votes

"Tu dois être informe, sans forme, comme l'eau. Quand tu verses de l'eau dans une tasse, elle devient la tasse. Quand tu verses de l'eau dans une bouteille, elle devient la bouteille. Quand tu verses de l'eau dans une théière, elle devient la théière. L'eau peut couler et elle peut s'écraser. Deviens comme l'eau mon ami." - Bruce Lee

6 votes

@Chef_Code Je suis désolé de ne pas avoir compris - en quoi votre citation est-elle pertinente pour la question posée, si vous me permettez de le demander ?

0 votes

Vous pouvez créer des classes en C++, à peu près comme en C#, c'est la principale différence entre C++ et C.

36voto

Mark Cidade Points 53945

Pour C# 3.0, les méthodes d'extension ne peuvent exister que dans les classes statiques de haut niveau.

28voto

user25306 Points 185

Si vous utilisez des outils d'analyse de code (par ex. FxCop ), il vous recommandera de marquer une méthode static si cette méthode n'accède pas aux données de l'instance. Le raisonnement est qu'il y a un gain de performance. MSDN : CA1822 - Marquer les membres comme statiques .

Il s'agit plus d'une ligne directrice que d'une règle, vraiment...

2 votes

En outre, une telle déclaration statique sur une méthode privée dans une classe d'instance transmet des informations supplémentaires utiles au développeur. Elle informe qu'une telle méthode statique privée ne modifie pas l'état de l'instance, c'est-à-dire que la méthode est une méthode utilitaire dans une classe.

13voto

Rob Points 1092

J'ai tendance à utiliser des classes statiques pour les fabriques. Par exemple, voici la classe de journalisation dans l'un de mes projets :

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}

Vous avez peut-être même remarqué que l'IoC est appelé avec un accesseur statique. Le plus Pour moi, la plupart du temps, si vous pouvez appeler des méthodes statiques sur une classe, c'est tout ce que vous pouvez faire, donc je marque la classe comme statique pour plus de clarté.

0 votes

Pourquoi définir un paramètre inutilisé dans la méthode générique ?

4 votes

@JohnClearZ peut-être parce qu'alors vous pouvez appeler For avec un objet existant et vous obtenez le logger correspondant sans penser au type réel de l'objet. Juste une supposition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X