J'ai vu d'autres développeurs utiliser des classes statiques comme espaces de noms
public static class CategoryA
{
public class Item1
{
public void DoSomething() { }
}
public class Item2
{
public void DoSomething() { }
}
}
public static class CategoryB
{
public class Item3
{
public void DoSomething() { }
}
public class Item4
{
public void DoSomething() { }
}
}
Pour instancier les classes internes, cela ressemblera à ceci:
CategoryA.Item1 item = new CategoryA.Item1();
La raison en est que les espaces de noms peuvent être masqués à l'aide du mot clé "using". Mais en utilisant les classes statiques, les noms des classes de la couche externe doivent être spécifiés, ce qui préserve efficacement les espaces de noms.
Microsoft déconseille cela dans les directives . Je pense personnellement que cela a un impact sur la lisibilité. Quelles sont vos pensées?
c#
c++
object-oriented
static-typing
namespace
user394128
la source
la source
Réponses:
L'utilisation de classes statiques comme espaces de noms défie le but d'avoir des espaces de noms.
La principale différence est ici:
Si vous définissez
CategoryA
, enCategoryB<
tant qu'espaces de noms, et lorsque l'application utilise deux espaces de noms:Ici, si
CategoryA
ouCategoryB
est une classe statique plutôt qu'un espace de noms, l'utilisation de l'application est presque la même que celle décrite ci-dessus.Cependant, si vous le définissez comme un espace de noms et que l'application n'utilise qu'un seul espace de noms (ne comprend pas
CategoryB
), dans ce cas, l'application peut réellement utiliser les éléments suivantsMais si vous aviez défini
CategoryA
une classe statique, ce qui précède n'est pas défini! On est obligé d'écrire àCategoryA.something
chaque fois.Les espaces de noms doivent être utilisés pour éviter les conflits de noms, tandis que la hiérarchie des classes doit être utilisée lorsque le regroupement de classes a une certaine pertinence pour le modèle de système.
la source
using Item1 = CategoryA.Item1
(je pense que cela fonctionne pour les classes imbriquées comme pour les espaces de noms)var s = new HideMe.MyPhoneNumberIs12345678.TheRealUsefulClass()
Ce qui se passe ici n'est certainement pas un code C # idiomatique.
Peut-être que ces autres essaient d'implémenter le modèle de module - cela vous permettrait d'avoir des fonctions, des actions, etc. ainsi que des classes dans «l'espace de noms» (c'est-à-dire une classe statique dans ce cas)?
la source
Tout d'abord, chaque classe devrait être dans un espace de noms, donc votre exemple serait en fait plus comme:
Cela dit, je ne vois aucun avantage à ce type de gymnastique de code lorsque vous pouvez tout aussi bien définir un tel espace de noms:
Si vous pensez peut-être un jour à stocker des méthodes statiques au niveau de la classe supérieure, cela pourrait avoir du sens, mais ce n'est toujours pas ce que les créateurs de C # ont à l'esprit, et pourrait simplement le rendre moins lisible pour les autres - je perdrais beaucoup de temps penser POURQUOI vous avez fait cela, et penser si je manque un fichier source qui fournirait des explications.
la source
Les espaces de noms en Java, JavaScript et .NET ne sont pas complets et ne permettent que de stocker des classes, mais pas d'autres choses comme les constantes ou les méthodes globales.
De nombreux développeurs utilisent les astuces "classes statiques" ou "méthodes statiques", même si certaines personnes ne le recommandent pas.
la source
Je sais que c'est une vieille question, mais une raison très valable d'utiliser une classe comme espace de noms (un non statique à cela) est que C # ne prend pas en charge la définition des espaces de noms paramétriques ou génériques. J'ai rédigé un article de blog sur ce sujet ici: http://tyreejackson.com/generics-net-part5-generic-namespaces/ .
L'essentiel est que, lors de l'utilisation de génériques pour résumer d'énormes portions de code passe-partout, il est parfois nécessaire de partager plusieurs paramètres génériques entre des classes et des interfaces liées. La manière conventionnelle de le faire serait de redéfinir les paramètres génériques, les contraintes et tout cela dans chaque interface et signature de classe. Au fil du temps, cela peut entraîner une prolifération de paramètres et de contraintes, sans parler de devoir constamment qualifier les types associés en transmettant les paramètres de type d'un type aux arguments de type du type associé.
L'utilisation d'une classe générique externe et l'imbrication des types associés au sein peuvent considérablement assécher le code et simplifier son abstraction. On peut ensuite dériver la classe d'espace de noms paramétrique avec une implémentation concrète qui fournit tous les détails concrets.
Voici un exemple trivial:
Utilisé comme ceci:
Consommez les dérivés comme ceci:
L'avantage d'écrire les types de cette manière est une sécurité de type accrue et moins de transtypage de types dans les classes abstraites. C'est l'équivalent de
ArrayList
vsList<T>
à plus grande échelle.la source