Chcę utworzyć alias dla nazwy klasy. Następująca składnia byłaby idealna:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
ale się nie skompiluje.
Przykład
Uwaga Ten przykład podano tylko dla wygody. Nie próbuj rozwiązywać tego konkretnego problemu, sugerując zmianę projektu całego systemu. Obecność lub brak tego przykładu nie zmienia pierwotnego pytania.
Część istniejącego kodu zależy od obecności klasy statycznej:
public static class ColorScheme
{
...
}
Ten schemat kolorów to schemat kolorów programu Outlook 2003. chcę wprowadzić schemat kolorów programu Outlook 2007, zachowując schemat kolorów programu Outlook 2003:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
Ale wciąż mam do czynienia z faktem, że kod zależy od obecności statycznej klasy o nazwie ColorScheme
. Moją pierwszą myślą było stworzenie ColorScheme
klasy, którą odziedziczę po jednym Outlook2003
lub Outlook2007
:
public static class ColorScheme : Outlook2007ColorScheme
{
}
ale nie możesz dziedziczyć z klasy statycznej.
Następną moją myślą było stworzenie ColorScheme
klasy statycznej , ale make Outlook2003ColorScheme
i Outlook2007ColorScheme
klasy nie są statyczne. Następnie zmienna statyczna w ColorScheme
klasie statycznej może wskazywać na „prawdziwy” schemat kolorów:
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
ale to wymagałoby ode mnie konwersji klasy składającej się całkowicie ze statycznych kolorów tylko do odczytu na właściwości, które można zastąpić, a następnie moja ColorScheme
klasa musiałaby mieć 30 różnych funkcji pobierających właściwości, które zostałyby przeniesione do zawartego obiektu.
To po prostu za dużo pisania.
Więc moją następną myślą było nadanie aliasu klasie:
public static ColorScheme = Outlook2007ColorScheme;
Ale to się nie kompiluje.
Jak mogę utworzyć alias dla klasy statycznej pod inną nazwą?
Aktualizacja: Czy ktoś może dodać odpowiedź „Nie możesz tego zrobić w C #” , więc mogę oznaczyć to jako zaakceptowaną odpowiedź. Każdy, kto chce odpowiedzieć na to samo pytanie, znajdzie to pytanie, zaakceptowaną odpowiedź i szereg obejść, które mogą być przydatne lub nie.
Chcę tylko zamknąć to pytanie.
źródło
interface
, który implementują wszystkie twoje klasy. Jak wspomniano w odpowiedzi Chills42 . Następnie można zdefiniować „usługę” lub „fabrykę”, która zwraca obiekt, który implementuje ten interfejs, w zależności od bieżących okoliczności (np. Platforma / system operacyjny) lub w pliku konfiguracyjnym.Odpowiedzi:
Nie możesz . Następna najlepsza rzecz można zrobić, to mieć
using
deklaracje w plikach, które wykorzystują klasę.Na przykład, możesz przepisać zależny kod używając aliasu importu (jako quasi-
typedef
substytut):using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Niestety musi to znaleźć się w każdym zasięgu / pliku, który używa tej nazwy.
Dlatego nie wiem, czy jest to praktyczne w twoim przypadku.
źródło
using
należy dodać do całego zepsutego kodu. A także neguje wartość posiadania pojedynczego aliasu, co pozwala mi przełączyć wszystkich użytkowników istniejącejColorScheme
klasy na użycie nowej klasy - bez zmian. Innymi słowy: chcę aliasowaćColorScheme
klasę do innej klasy.Możesz utworzyć alias dla swojej klasy, dodając następujący wiersz kodu:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
źródło
Imports
. Czy się mylę?using
dyrektywę w jej przestrzeni nazw, np. Gdy potrzebujesz aliasu własnej klasy.Chcesz ( Factory | Singleton ), w zależności od twoich wymagań. Założeniem jest to, aby kod klienta nie musiał wiedzieć, jaki schemat kolorów otrzymuje. Jeśli schemat kolorów ma być szeroki w aplikacji, pojedynczy powinien wystarczyć. Jeśli możesz użyć innego schematu w innych okolicznościach, prawdopodobnie najlepszym rozwiązaniem będzie wzorzec Factory. Tak czy inaczej, gdy trzeba zmienić schemat kolorów, kod wystarczy zmienić tylko w jednym miejscu.
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; } } }
źródło
Nie można utworzyć aliasu nazwy klasy w języku C #.
Są rzeczy, które możesz zrobić, a nie aliasowanie nazwy klasy w języku C #.
Ale odpowiadając na pierwotne pytanie: nie możesz aliasować nazwy klasy w C #.
Aktualizacja: Ludzie są zdezorientowani, dlaczego
using
nie działa. Przykład: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) { ... } }
I wszystko działa. Teraz chcę utworzyć nową klasę i alias
ColorScheme
do niej (aby nie trzeba było modyfikować kodu ):ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme; class Outlook2007ColorScheme { public static Color ApplyColorScheme(Color c) { ... } }
Och, przepraszam. Ten kod nie kompiluje się:
Moje pytanie dotyczyło aliasu klasy w C #. Nie da się tego zrobić. Są rzeczy, które mogę zrobić, że są nie aliasing nazwę klasy w języku C #:
ColorScheme
abyusing
ColorScheme
zamiast (zmiana obejście kodu, ponieważ nie mogę alias)ColorScheme
aby używały wzorca fabrycznego, im polimorficzną klasę lub interfejs (obejście zmiany kodu, ponieważ nie mogę aliasu)Ale te obejścia obejmują złamanie istniejącego kodu: nie jest to opcja.
Jeśli ludzie polegają na obecności
ColorScheme
klasy, muszę faktycznie skopiować / wkleić plikColorScheme
klasę.Innymi słowy: nie mogę aliasować nazwy klasy w C #.
Kontrastuje to z innymi językami obiektowymi, w których mógłbym zdefiniować alias:
i byłbym skończony.
źródło
Spróbuj tego:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
źródło
Dodaję ten komentarz dla użytkowników, którzy znaleźli to długo po tym, jak OP zaakceptował ich „odpowiedź”. Aliasowanie w C # działa przez określenie nazwy klasy przy użyciu jej w pełni kwalifikowanej przestrzeni nazw. Jeden zdefiniowany, alias może być używany w jego zakresie. Przykład.
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 } }
Przepraszamy za szybko wpisany kod, ale miejmy nadzieję, że wyjaśnia, jak należy to zaimplementować, aby użytkownicy nie wprowadzali w błąd, wierząc, że nie można tego zrobić w C #.
źródło
namespace Fully.Qualified.Namespace{
public class Example {
...public void DoStuff(){
...}
...}
}
.Aliasowanie w sposób, w jaki chciałbyś to zrobić, nie zadziała w C #. Dzieje się tak, ponieważ aliasing jest wykonywany przez
using
dyrektywę, która jest ograniczona do danego pliku / przestrzeni nazw. Jeśli masz 50 plików, które używają starej nazwy klasy, będzie to oznaczać 50 miejsc do zaktualizowania.To powiedziawszy, myślę, że istnieje proste rozwiązanie, dzięki któremu zmiana kodu będzie jak najmniejsza. Spraw, aby
ColorScheme
klasa stała się fasadą dla twoich wywołań klas rzeczywistych z implementacją i użyjusing
w tym pliku, aby określić, którejColorScheme
używasz.Innymi słowy, zrób to:
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); } }
Następnie w swoim kodzie z tyłu nic nie zmieniaj:
private void button1_Click(object sender, EventArgs e) { this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor); }
Następnie możesz zaktualizować wartości
ColorScheme
, aktualizując jeden wiersz kodu (using CurrentColorScheme = Outlook2008ColorScheme;
).Kilka wątpliwości:
ColorScheme
klasy i doOutlook2007ColorScheme
klasy. To dodatkowa praca, ale jeśli jest to prawdziwy starszy kod, nie powinno to być częste. Jako bonus, kodColorScheme
jest tak prosty, że każdy możliwy błąd jest bardzo oczywisty.ColorScheme
klasę, którą zastępujesz, to i każde inne podejście może stanowić problem. Radziłbym zmienić nazwę tej klasy na podobnąColorSchemeOld
, a następnie uzyskać do niej dostęp za pośrednictwemusing CurrentColorScheme = ColorSchemeOld;
.źródło
Przypuszczam, że zawsze można dziedziczyć z klasy bazowej bez niczego dodanego
public class Child : MyReallyReallyLongNamedClass {}
AKTUALIZACJA
Ale jeśli masz możliwość refaktoryzacji
class
samej siebie: nazwa klasy jest zwykle niepotrzebnie długa z powodu brakunamespace
s.Jeśli widzisz przypadki jak
ApiLoginUser
,DataBaseUser
,WebPortalLoginUser
, jest zwykle wskazanie brakunamespace
należytej strachu, że nazwaUser
konfliktu sił.W takim przypadku możesz jednak użyć
namespace
aliasu , jak wskazano w powyższych postachusing 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);
Zwróć uwagę, że wszystkie
class
nazwy sąUser
, ale w różnychnamespace
. Cytując PEP-20: Zen of Python :Mam nadzieję że to pomoże
źródło
new
słów kluczowych dla takich metod lub nawet wymyślić własne ExtensionMethods, prawda? W każdym razie uważam, że zawsze powinieneś używać klas Vanilla Collection (tj. Dictionary, List, IEnumerable, IQueryable, itp.) Z niestandardowymi modelami / ViewModels / POCO. Jak twierdzi Mvc: Konwencja nad konfiguracjąIColorScheme oColorScheme = ColorSchemeFactory.Create();
Możesz również zajrzeć do Dependency InjectionCzy można przejść na używanie interfejsu?
Może mógłbyś stworzyć
IColorScheme
interfejs, który implementują wszystkie klasy?To działałoby dobrze ze wzorem fabrycznym, jak pokazał Chris Marasti-Georg
źródło
To bardzo późna odpowiedź częściowa - ale jeśli zdefiniujesz tę samą klasę `` ColorScheme '', w tej samej przestrzeni nazw `` Outlook '', ale w oddzielnych zestawach, jeden o nazwie Outlook2003, a drugi Outlook2007, wszystko, co musisz zrobić, to odwołać się do odpowiedniego zestawu .
źródło