Dans mon projet actuel, j'ai rencontré la nécessité de créer des classes génériques avec le même nom, mais différents nombres de paramètres génériques. Par exemple:
MyClass<T1>
MyClass<T1, T2>
MyClass<T1, T2, T3>
Étant donné que je veux tous ces éléments dans le même espace de noms, je ne sais pas comment structurer et nommer mes classes et fichiers?
Si nous suivons l'idée que nous devrions avoir des classes limitées à une par fichier et que les fichiers doivent être dans une structure de dossiers qui représente la hiérarchie des espaces de noms et que le nom du fichier doit correspondre au nom de la classe, comment gérer cette situation ?
Ce que je demande vraiment ici, c'est que dois-je nommer le fichier qui contient MyClass<T1>
et que dois-je nommer le fichier qui contient MyClass<T1, T2>
? Je ne demande pas quels devraient être les noms des paramètres de type.
TKey, TValue
convention. Func a unTResult
paramètre de type. Bien que je suis d' accord que vous pouvez utiliserT1
,T2
etc. pour un nombre variable de paramètres d'entrée qui n'ont pas autrement utilisations spécifiques commeTKey
etTValue
.Réponses:
Et ainsi de suite, où le nombre après le backtick est le nombre de paramètres de type générique. Cette convention est utilisée par Microsoft.
Alternativement, vous pouvez utiliser quelque chose comme
qui conserve non seulement le nombre de paramètres de type génériques, mais aussi leurs noms spécifiques. Certes, cela ne préserve pas les équerres, mais nous ne pouvons pas avoir tout ce que nous voulons dans la vie, n'est-ce pas?
la source
Dans le cas de
Tuple
etAction
que Pete a mentionné, Microsoft utilise lui-même un seul fichier - voir Tuple.cs et Action.cs .Je pense que cela dépend en partie du fait que la fonctionnalité de toutes les classes soit ou non la même. Personnellement, je n'aime pas regrouper les classes dans un seul fichier, mais cela pourrait être une exception. Dans le code source où je travaille, j'ai ajouté une génération automatique (en utilisant T4)
NamedTuple
qui agit de la même manière queTuple
, mais avec un nom de chaîne comme premier argument dans le constructeur.Pour répondre à votre question, si vous ne souhaitez pas utiliser un seul fichier, utilisez peut-être MyClass_1.cs pour
MyClass<T1>
, MyClass_2.cs pourMyClass<T1, T2>
, etc.Aucune des deux options n'est cependant idéale, donc je serais enclin à suggérer l'argument "Microsoft fais comme ça, alors ...".
la source
Tuple
etAction
sont tous des délégués; ils n'ont pas de code d'implémentation, donc mettre toutes les variations dans des fichiers séparés serait de toute façon inutile. Prouve simplement que chaque règle a une exception.Tuple
n'est pas un délégué, mais chaque implémentation est de toute façon courte.Func
.Vous êtes-vous demandé si les cours ont vraiment la même intention? Si une classe est plus générique que l'autre, alors ce sera un GenericClass , un MoreGenericClass et un MostGenericClass . Imaginez que chaque paramètre de type d'une classe ajoute une nouvelle dimension à la classe, il peut donc être utile de demander de quelle dimension il s'agit.
Prenons cet exemple:
Container<Thing>
MetricContainer<Thing, Metric>
MetricTransportableContainer<Thing, Metric, Transport>
Je suis conscient que ce n'est pas le meilleur exemple, mais très expressif pour montrer trois dimensions:
Vous pouvez donc modéliser le transport de voitures:
Transport de fluides:
Transport d'énergie:
Transport de sucre, céréales:
Oh, quelle surprise: a
List<T>
a une dimension qui représente les choses que la liste peut contenir; et c'est unMap<T, S>
à deux dimensions qui représentent les choses que la carte peut contenir et les clés d'accès.la source
Tuple<T1>
,Tuple<T1, T2>
etTuple<T1, T2, T3>
dans des fichiers CS séparés de manière standard, sans conflits de noms?