Je souhaite créer un alias pour un nom de classe. La syntaxe suivante serait parfaite:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
mais il ne se compilera pas.
Exemple
Remarque Cet exemple est fourni à titre indicatif uniquement. N'essayez pas de résoudre ce problème particulier en suggérant de modifier la conception de l'ensemble du système. La présence, ou l'absence, de cet exemple ne change pas la question d'origine.
Certains codes existants dépendent de la présence d'une classe statique:
public static class ColorScheme
{
...
}
Ce jeu de couleurs est le jeu de couleurs Outlook 2003. Je souhaite introduire un jeu de couleurs Outlook 2007, tout en conservant le jeu de couleurs Outlook 2003:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
Mais je suis toujours confronté au fait que le code dépend de la présence d'une classe statique appelée ColorScheme
. Ma première pensée a été de créer une ColorScheme
classe dont j'hériterai de l'un Outlook2003
ou l' autre Outlook2007
:
public static class ColorScheme : Outlook2007ColorScheme
{
}
mais vous ne pouvez pas hériter d'une classe statique.
Ma prochaine pensée a été de créer la ColorScheme
classe statique , mais make Outlook2003ColorScheme
et les Outlook2007ColorScheme
classes non statiques. Ensuite, une variable statique de la ColorScheme
classe statique peut pointer vers l'un ou l'autre des jeux de couleurs "vrais":
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
mais cela m'obligerait à convertir une classe composée entièrement de couleurs statiques en lecture seule en propriétés remplaçables, puis ma ColorScheme
classe aurait besoin d'avoir les 30 propriétés différentes getters thunk dans l'objet contenu.
C'est juste trop de frappe.
Ma prochaine pensée était donc d'aliaser la classe:
public static ColorScheme = Outlook2007ColorScheme;
Mais cela ne compile pas.
Comment puis-je aliaser une classe statique en un autre nom?
Mise à jour: quelqu'un peut-il ajouter la réponse "Vous ne pouvez pas faire cela en C #" , afin que je puisse marquer cela comme la réponse acceptée. Toute autre personne souhaitant obtenir une réponse à la même question trouvera cette question, la réponse acceptée et un certain nombre de solutions de contournement qui pourraient ou non être utiles.
Je veux juste clore cette question.
la source
interface
, que toutes vos classes implémentent. Comme mentionné dans la réponse de chills42 . Vous pouvez alors définir un «service» ou une «usine» qui retourne un objet qui implémente cette interface, selon les circonstances actuelles (par exemple plate-forme / OS) ou sur un fichier de configuration.Réponses:
Vous ne pouvez pas . La prochaine meilleure chose que vous puissiez faire est d'avoir des
using
déclarations dans les fichiers qui utilisent la classe.Par exemple, vous pouvez réécrire le code dépendant en utilisant un alias d'importation (comme quasi-
typedef
substitut):using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Malheureusement, cela doit aller dans chaque portée / fichier qui utilise le nom.
Je ne sais donc pas si cela est pratique dans votre cas.
la source
using
doit être ajouté à tout code cassé. Et cela annule également la valeur d'avoir un seul alias, ce qui me permet de basculer tous les utilisateurs de laColorScheme
classe existante vers une nouvelle classe - sans modifications. En d'autres termes: je veux alias laColorScheme
classe vers une autre classe.Vous pouvez créer un alias pour votre classe en ajoutant cette ligne de code:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
la source
Imports
. Ai-je tort?using
directive dans son espace de noms, par exemple lorsque vous avez besoin d'un alias de votre propre classe.Vous voulez un ( Factory | Singleton ), en fonction de vos besoins. Le principe est de faire en sorte que le code client n'ait pas à savoir quel jeu de couleurs il obtient. Si la palette de couleurs doit être étendue à l'application, un singleton devrait convenir. Si vous pouvez utiliser un schéma différent dans des circonstances différentes, un motif Factory est probablement la voie à suivre. Dans tous les cas, lorsque le jeu de couleurs doit changer, le code ne doit être changé qu'à un seul endroit.
public interface ColorScheme { Color TitleBar { get; } Color Background{ get; } ... } public static class ColorSchemeFactory { private static ColorScheme scheme = new Outlook2007ColorScheme(); public static ColorScheme GetColorScheme() { //Add applicable arguments return scheme; } } public class Outlook2003ColorScheme: ColorScheme { public Color TitleBar { get { return Color.LightBlue; } } public Color Background { get { return Color.Gray; } } } public class Outlook2007ColorScheme: ColorScheme { public Color TitleBar { get { return Color.Blue; } } public Color Background { get { return Color.White; } } }
la source
Vous ne pouvez pas aliaser un nom de classe en C #.
Il y a des choses que vous pouvez faire sans aliaser un nom de classe en C #.
Mais pour répondre à la question d'origine: vous ne pouvez pas aliaser un nom de classe en C #.
Mise à jour: les gens ne savent pas pourquoi
using
cela ne fonctionne pas. Exemple:Form1.cs
private void button1_Click(object sender, EventArgs e) { this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor); }
ColorScheme.cs
class ColorScheme { public static Color ApplyColorScheme(Color c) { ... } }
Et tout fonctionne. Maintenant, je veux créer une nouvelle classe et lui attribuer un alias
ColorScheme
(afin qu'aucun code ne doive être modifié ):ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme; class Outlook2007ColorScheme { public static Color ApplyColorScheme(Color c) { ... } }
Ohh, je suis désolé. Ce code ne compile pas:
Ma question était de savoir comment aliaser une classe en C #. Cela ne peut pas être fait. Il y a des choses que je peux faire sans aliaser un nom de classe en C #:
ColorScheme
à lausing
ColorScheme
place (solution de contournement de changement de code car je ne peux pas créer d'alias)ColorScheme
pour utiliser un modèle d'usine, une classe ou une interface polymorphe (solution de contournement de changement de code car je ne peux pas créer d'alias)Mais ces solutions de contournement impliquent de casser le code existant: pas une option.
Si les gens dépendent de la présence d'une
ColorScheme
classe, je dois en fait copier / coller uneColorScheme
classe.En d'autres termes: je ne peux pas aliaser un nom de classe en C #.
Cela contraste avec d'autres langages orientés objet, où je pourrais définir l'alias:
et j'aurais fini.
la source
essaye ça:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
la source
J'ajoute ce commentaire pour les utilisateurs qui le trouvent longtemps après que OP ait accepté leur "réponse". L'alias en C # fonctionne en spécifiant le nom de la classe à l'aide de son espace de noms complet. Une fois défini, le nom d'alias peut être utilisé dans sa portée. Exemple.
using aliasClass = Fully.Qualified.Namespace.Example; //Example being the class in the Fully.Qualified.Namespace public class Test{ public void Test_Function(){ aliasClass.DoStuff(); //aliasClass here representing the Example class thus aliasing //aliasClass will be in scope for all code in my Test.cs file } }
Toutes mes excuses pour le code rapidement tapé, mais j'espère qu'il explique comment cela devrait être implémenté afin que les utilisateurs ne soient pas induits en erreur en pensant que cela ne peut pas être fait en C #.
la source
namespace Fully.Qualified.Namespace{
public class Example {
...public void DoStuff(){
...}
...}
}
.Aliasing comme vous le souhaitez ne fonctionnera pas en C #. Cela est dû au fait que l'aliasing se fait via la
using
directive, qui est limitée au fichier / espace de noms en question. Si vous avez 50 fichiers qui utilisent l'ancien nom de classe, cela signifie 50 emplacements à mettre à jour.Cela dit, je pense qu'il existe une solution simple pour rendre votre changement de code aussi minime que possible. Faites de la
ColorScheme
classe une façade pour vos appels aux classes réelles avec l'implémentation, et utilisez leusing
dans ce fichier pour déterminer lequelColorScheme
vous utilisez.En d'autres termes, procédez comme suit:
using CurrentColorScheme = Outlook2007ColorScheme; public static class ColorScheme { public static Color ApplyColorScheme(Color c) { return CurrentColorScheme.ApplyColorScheme(c); } public static Something DoSomethingElse(Param a, Param b) { return CurrentColorScheme.DoSomethingElse(a, b); } }
Ensuite, dans votre code derrière, ne changez rien:
private void button1_Click(object sender, EventArgs e) { this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor); }
Vous pouvez ensuite mettre à jour les valeurs de
ColorScheme
en mettant à jour une ligne de code (using CurrentColorScheme = Outlook2008ColorScheme;
).Quelques préoccupations ici:
ColorScheme
classe et à laOutlook2007ColorScheme
classe. C'est un travail supplémentaire, mais s'il s'agit d'un vrai code hérité, cela ne devrait pas être fréquent. En prime, le codeColorScheme
est si simple que tout bogue éventuel est très évident.ColorScheme
classe que vous remplacez, cette approche et toute autre pourraient être un problème. Je vous conseillerais de renommer cette classe en quelque chose commeColorSchemeOld
, puis d'y accéder viausing CurrentColorScheme = ColorSchemeOld;
.la source
Je suppose que vous pouvez toujours hériter de la classe de base sans rien ajouté
public class Child : MyReallyReallyLongNamedClass {}
MISE À JOUR
Mais si vous avez la capacité de refactoriser le
class
lui - même: Un nom de classe est généralement inutilement long en raison du manque denamespace
s.Si vous voyez des cas comme
ApiLoginUser
,DataBaseUser
,WebPortalLoginUser
, est généralement indication du manque denamespace
raison de la crainte que le nomUser
pourrait entrer en conflit.Dans ce cas cependant, vous pouvez utiliser un
namespace
alias , comme cela a été souligné dans les articles ci-dessususing LoginApi = MyCompany.Api.Login; using AuthDB = MyCompany.DataBase.Auth; using ViewModels = MyCompany.BananasPortal.Models; // ... AuthDB.User dbUser; using ( var ctxt = new AuthDB.AuthContext() ) { dbUser = ctxt.Users.Find(userId); } var apiUser = new LoginApi.Models.User { Username = dbUser.EmailAddess, Password = "*****" }; LoginApi.UserSession apiUserSession = await LoginApi.Login(apiUser); var vm = new ViewModels.User(apiUserSession.User.Details); return View(vm);
Notez comment les
class
noms sont tousUser
, mais dans desnamespace
s différents . Citant PEP-20: Zen of Python :J'espère que cela t'aides
la source
new
mots clés pour de telles méthodes ou même proposer vos propres méthodes d'extension, non? Dans tous les cas, je suis convaincu que vous devriez toujours utiliser des classes de collection vanilla (ie Dictionary, List, IEnumerable, IQueryable, etc.) avec des modèles / ViewModels / POCO personnalisés. Comme le dit Mvc: Convention over ConfigurationIColorScheme oColorScheme = ColorSchemeFactory.Create();
Aussi, vous voudrez peut-être examiner l' injection de dépendanceEst-il possible de passer à l'utilisation d'une interface?
Peut-être pourriez-vous créer une
IColorScheme
interface que toutes les classes implémentent?Cela fonctionnerait bien avec le modèle d'usine comme le montre Chris Marasti-Georg
la source
C'est une réponse partielle très tardive - mais si vous définissez la même classe 'ColorScheme', dans le même espace de noms 'Outlook', mais dans des assemblys séparés, l'un appelé Outlook2003 et l'autre Outlook2007, alors tout ce que vous avez à faire est de référencer l'assemblage approprié .
la source