Come faccio ad alias un nome di class in C #?

Voglio creare un alias per un nome di class. La seguente syntax sarebbe perfetta:

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName { ... } public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName; 

ma non verrà compilato.


Esempio

Nota Questo esempio è fornito solo per comodità. Non cercare di risolvere questo particolare problema suggerendo di cambiare il design dell’intero sistema. La presenza o la mancanza di questo esempio non cambia la domanda originale.

Alcuni codici esistenti dipendono dalla presenza di una class statica:

 public static class ColorScheme { ... } 

Questa combinazione di colors è la combinazione di colors di Outlook 2003. Voglio introdurre una combinazione di colors di Outlook 2007, pur mantenendo lo schema di colors di Outlook 2003:

 public static class Outlook2003ColorScheme { ... } public static class Outlook2007ColorScheme { ... } 

Ma sono ancora di fronte al fatto che il codice dipende dalla presenza di una class statica chiamata ColorScheme. Il mio primo pensiero è stato quello di creare una class ColorScheme che discenderò da Outlook2003 o Outlook2007:

 public static class ColorScheme : Outlook2007ColorScheme { } 

ma non puoi discendere da una class statica.

Il mio prossimo pensiero è stato quello di creare la class statica di ColorScheme, ma rendere le classi di Outlook2003ColorScheme e Outlook2007ColorScheme non statiche. Quindi una variabile statica nella class ColorScheme statica può puntare a uno schema di colors “vero”:

 public static class ColorScheme { private static CustomColorScheme = new Outlook2007ColorScheme(); ... } private class CustomColorScheme { ... } private class Outlook2008ColorScheme : CustomColorScheme { ... } private class Outlook2003ColorScheme : CustomColorScheme { ... } 

ma ciò richiederebbe la conversione di una class composta interamente da colors statici readonly in proprietà sovrascrivibili, e quindi la mia class ColorScheme avrebbe bisogno di abbattere i 30 getters di proprietà differenti nell’object contenuto.

Questo è solo un eccesso di battitura.

Quindi il mio prossimo pensiero è stato quello di alias della class:

 public static ColorScheme = Outlook2007ColorScheme; 

Ma questo non si compila.

Come posso fare un alias di una class statica in un altro nome?


Aggiornamento: qualcuno può aggiungere la risposta “Non puoi farlo in C #” , quindi posso contrassegnarlo come risposta accettata. Chiunque desideri ottenere la risposta alla stessa domanda troverà questa domanda, la risposta accettata e una serie di soluzioni alternative che potrebbero, o potrebbero non essere, essere utili.

Voglio solo chiudere questa domanda.

    Se si modifica il nome della class originale, è ansible riscrivere il codice dipendente utilizzando un alias di importazione come sostituto typedef :

     using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme; 

    Questo deve andare nella parte superiore del file / spazio dei nomi, proprio come normale using s.

    Non so se questo è pratico nel tuo caso, però.

    Puoi creare un alias per la tua class aggiungendo questa riga di codice:

     using Outlook2007ColorScheme = YourNameSpace.ColorScheme; 

    Vuoi un ( Factory | Singleton ), a seconda delle tue esigenze. La premessa è di fare in modo che il codice client non debba sapere quale combinazione di colors sta ottenendo. Se lo schema dei colors dovesse essere esteso a tutta l’applicazione, un singleton dovrebbe andare bene. Se è ansible utilizzare uno schema diverso in circostanze diverse, è probabile che uno schema di fabbrica sia la scelta giusta. In ogni caso, quando lo schema dei colors deve cambiare, il codice deve essere modificato solo in un posto.

     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; } } } 

    Non puoi fare l’alias di un nome di class in C #.

    Ci sono cose che puoi fare che non sono aliasing di un nome di class in C #.

    Ma per rispondere alla domanda originale: non è ansible creare un alias per un nome di class in C #.


    Aggiornamento: le persone sono confuse perché l’ using non funziona. Esempio:

    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) { ... } } 

    E tutto funziona. Ora voglio creare una nuova class e creare alias ColorScheme (in modo che nessun codice debba essere modificato ):

    ColorScheme.cs

     using ColorScheme = Outlook2007ColorScheme; class Outlook2007ColorScheme { public static Color ApplyColorScheme(Color c) { ... } } 

    Ohh, mi dispiace. Questo codice non viene compilato:

    inserisci la descrizione dell'immagine qui

    La mia domanda era come alias una class in C #. Non può essere fatto. Ci sono cose che posso fare che non sono aliasing di un nome di class in C #:

    • cambiare tutti coloro che dipendono da ColorScheme per l’ using ColorScheme (soluzione di modifica del codice perché non posso alias)
    • cambia tutti coloro che dipendono da ColorScheme per utilizzare una serie di modelli o un’interfaccia polimorfica di fabbrica (soluzione di modifica del codice perché non posso alias)

    Ma queste soluzioni alternative comportano la rottura del codice esistente: non un’opzione.

    Se le persone dipendono dalla presenza di una class ColorScheme , devo effettivamente copiare / incollare una class ColorScheme .

    In altre parole: non posso aliasare un nome di class in C #.

    Questo contrasta con altri linguaggi object oriented, in cui potrei definire l’alias:

     ColorScheme = Outlook2007ColorScheme 

    e sarei fatto.

    prova questo:

     using ColorScheme=[fully qualified].Outlook2007ColorScheme 

    L’aliasing nel modo in cui vorresti farlo non funzionerà in C #. Questo perché l’aliasing viene eseguito tramite la direttiva using , che è limitata al file / spazio dei nomi in questione. Se hai 50 file che usano il vecchio nome della class, ciò significa 50 posti da aggiornare.

    Detto questo, penso che ci sia una soluzione semplice per rendere il tuo codice il più minimale ansible. Rendi la class ColorScheme una facciata per le tue chiamate alle classi effettive con l’implementazione, e usa l’ using in quel file per determinare quale ColorScheme usi.

    In altre parole, fai questo:

     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); } } 

    Quindi, nel tuo codice, non modificare nulla:

     private void button1_Click(object sender, EventArgs e) { this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor); } 

    È quindi ansible aggiornare i valori di ColorScheme aggiornando una riga di codice ( using CurrentColorScheme = Outlook2008ColorScheme; ).

    Un paio di preoccupazioni qui:

    • Ogni nuovo metodo o definizione di proprietà dovrà quindi essere aggiunto in due punti, alla class ColorScheme e alla class Outlook2007ColorScheme . Questo è un lavoro extra, ma se questo è vero codice legacy, non dovrebbe essere un evento frequente. Come bonus, il codice in ColorScheme è così semplice che ogni ansible bug è molto ovvio.
    • Questo uso di classi statiche non mi sembra naturale; Probabilmente proverei a rifattorizzare il codice legacy per farlo in modo diverso, ma capisco anche che la tua situazione potrebbe non permetterlo.
    • Se hai già una class ColorScheme che stai sostituendo, questo approccio e qualsiasi altro potrebbe essere un problema. Ti consiglierei di rinominare quella class con qualcosa come ColorSchemeOld e quindi accedervi using CurrentColorScheme = ColorSchemeOld; .

    Suppongo che puoi sempre ereditare dalla class base senza aggiungere nulla

     public class Child : MyReallyReallyLongNamedClass {} 

    AGGIORNARE

    Ma se si ha la capacità di refactoring della class stessa: un nome di class è solitamente inutilmente lungo a causa della mancanza di namespace dei namespace .

    Se si vedono i casi come ApiLoginUser , DataBaseUser , WebPortalLoginUser , in genere indica l’assenza di namespace dei namespace causa del timore che il nome User possa ApiLoginUser conflitto.

    In questo caso, tuttavia, è ansible utilizzare l’alias dello namespace , come è stato indicato nei post precedenti

     using 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); 

    Nota come i nomi delle class sono tutti User , ma in diversi namespace s. Citando PEP-20: Zen of Python :

    I namespace sono una delle grandi idee – facciamo di più!

    Spero che questo ti aiuti

    Sto aggiungendo questo commento per gli utenti che lo trovano molto tempo dopo che OP ha accettato la loro “risposta”. L’aliasing in C # funziona specificando il nome della class usando il suo spazio dei nomi completo. Uno definito, il nome alias può essere utilizzato all’interno del suo ambito. Esempio.

     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 } } 

    Ci scusiamo per il codice digitato rapidamente, ma spero che spieghi come dovrebbe essere implementato in modo che gli utenti non siano indotti in errore nel credere che non possa essere fatto in C #.

    È ansible passare all’utilizzo di un’interfaccia?

    Forse potresti creare un’interfaccia IColorScheme che tutte le classi implementano?

    Ciò funzionerebbe bene con il modello di fabbrica, come mostrato da Chris Marasti-Georg

    È una risposta parziale molto tardiva – ma se si definisce la stessa class ‘ColorScheme’, nello stesso spazio dei nomi ‘Outlook’, ma in assembly separati, uno chiamato Outlook2003 e l’altro Outlook2007, allora tutto ciò che si deve fare è fare riferimento all’assemblaggio appropriato .