Как я называю имя класса в С#?
Я хочу создать псевдоним для имени класса. Следующий синтаксис был бы идеальным:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
но он не будет компилироваться.
Пример
Примечание Этот пример предоставляется только для удобства. Не пытайтесь решить эту проблему, предлагая изменить дизайн всей системы. Присутствие или отсутствие этого примера не изменяет исходный вопрос.
Некоторые существующие коды зависят от наличия статического класса:
public static class ColorScheme
{
...
}
Эта цветовая схема - это цветовая схема Outlook 2003. Я хочу представить цветовую схему Outlook 2007, сохраняя при этом цветовую схему Outlook 2003:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
Но я все еще сталкиваюсь с тем, что код зависит от наличия статического класса ColorScheme. Моя первая мысль заключалась в том, чтобы создать класс ColorScheme, который я буду опускать либо из Outlook2003, либо из Outlook2007:
public static class ColorScheme : Outlook2007ColorScheme
{
}
но вы не можете спуститься со статического класса.
Моя следующая мысль заключалась в том, чтобы создать статический класс ColorScheme, но сделать классы Outlook2003ColorScheme и Outlook2007ColorScheme нестационарными. Затем статическая переменная в статическом классе ColorScheme может указывать либо на "истинную" цветовую схему:
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
но это потребовало бы, чтобы я преобразовал класс, состоящий из readonly static Colors, в переопределяемые свойства, а затем мой класс ColorScheme должен был бы иметь 30 разных свойств getters вниз в содержащийся объект.
Это слишком много печатает.
Итак, моя следующая мысль заключалась в том, чтобы псевдоним класса:
public static ColorScheme = Outlook2007ColorScheme;
Но это не компилируется.
Как я могу добавить статический класс в другое имя?
Обновление: Может кто-нибудь добавить ответ "Вы не можете сделать это на С#", поэтому я могу отметить это как принятый ответ. Любой, кто хочет ответить на один и тот же вопрос, найдет этот вопрос, принятый ответ и ряд обходных путей, которые могут или могут быть полезны.
Я просто хочу закрыть этот вопрос.
Ответы
Ответ 1
Вы не можете псевдонизировать имя класса в С#.
Есть вещи, которые вы можете сделать, которые не накладывают имя класса на С#.
Но чтобы ответить на исходный вопрос: вы не можете псевдонизировать имя класса в С#.
Обновление: Люди путаются, почему using
не работает. Пример:
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) { ... }
}
И все работает. Теперь я хочу создать новый класс и псевдоним ColorScheme
для него (так что код не должен быть изменен):
ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme;
class Outlook2007ColorScheme
{
public static Color ApplyColorScheme(Color c) { ... }
}
Ой, извините. Этот код не компилируется:
![enter image description here]()
Мой вопрос заключался в том, как псевдоним класса на С#. Это невозможно. Есть вещи, которые я могу сделать, которые не накладывают имя класса в С#:
- измените всех, кто зависит от
ColorScheme
до using
ColorScheme
вместо этого (обходное изменение кода, потому что я не могу использовать псевдоним)
- изменить всех, кто зависит от
ColorScheme
, использовать шаблон factory для них полиморфный класс или интерфейс (обходное изменение кода, потому что я не могу использовать псевдоним)
Но эти обходные пути включают нарушение существующего кода: не вариант.
Если люди зависят от наличия класса ColorScheme
, я должен фактически скопировать/вставить класс ColorScheme
.
Другими словами: я не могу псевдонизировать имя класса в С#.
Это контрастирует с другими объектно-ориентированными языками, где я мог бы определить псевдоним:
ColorScheme = Outlook2007ColorScheme
и я буду готов.
Ответ 2
Если вы измените исходное имя класса, вы можете переписать зависимый код с помощью псевдонима импорта в качестве замены typedef
:
using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Это должно быть в верхней части пространства файлов/имен, как обычно, using
s.
Я не знаю, насколько это практично в вашем случае.
Ответ 3
Вы можете сделать псевдоним для своего класса, добавив эту строку кода:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
Ответ 4
Вы хотите (Factory | Singleton), в зависимости от ваших требований. Предпосылка заключается в том, чтобы сделать так, чтобы клиентский код не должен был знать, какую цветовую схему он получает. Если цветовая схема должна быть широко применена, синглтон должен быть в порядке. Если вы можете использовать другую схему в разных обстоятельствах, шаблон Factory - это, вероятно, путь. В любом случае, когда цветовая схема должна измениться, код нужно изменить только в одном месте.
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; }
}
}
Ответ 5
попробуйте следующее:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
Ответ 6
Если вы хотите, чтобы это было не так, вы бы не работали на С#. Это связано с тем, что aliasing выполняется с помощью директивы using
, которая ограничена рассматриваемым файлом/пространством имен. Если у вас есть 50 файлов, которые используют старое имя класса, это будет означать 50 мест для обновления.
Тем не менее, я думаю, что есть простое решение, чтобы сделать ваш код как можно более минимальным. Сделайте класс ColorScheme
фасад для ваших вызовов фактическим классам с реализацией и используйте using
в этом файле, чтобы определить, какой ColorScheme
вы используете.
Другими словами, сделайте следующее:
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);
}
}
Затем в вашем коде позади ничего не измените:
private void button1_Click(object sender, EventArgs e)
{
this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
Затем вы можете обновить значения ColorScheme
, обновив одну строку кода (using CurrentColorScheme = Outlook2008ColorScheme;
).
Здесь пара относится:
- Затем каждый новый метод или определение свойства необходимо добавить в двух местах, в класс
ColorScheme
и в класс Outlook2007ColorScheme
. Это дополнительная работа, но если это истинный код устаревшего кода, это не должно быть частым появлением. В качестве бонуса код в ColorScheme
настолько прост, что любая возможная ошибка очень очевидна.
- Это использование статических классов для меня не кажется естественным; Я, вероятно, попытаюсь реорганизовать устаревший код, чтобы сделать это по-другому, но я также понимаю, что ваша ситуация может этого не допускать.
- Если у вас уже есть класс
ColorScheme
, который вы заменяете, этот подход и любой другой могут быть проблемой. Я бы посоветовал вам переименовать этот класс в нечто вроде ColorSchemeOld
, а затем получить доступ к нему через using CurrentColorScheme = ColorSchemeOld;
.
Ответ 7
Я предполагаю, что вы всегда можете наследовать из базового класса без добавления
public class Child : MyReallyReallyLongNamedClass {}
ОБНОВЛЕНИЕ
Но если у вас есть возможность рефакторинга самого class
: имя класса обычно излишне длинное из-за отсутствия namespace
s.
Если вы видите случаи как ApiLoginUser
, DataBaseUser
, WebPortalLoginUser
, обычно указывает на отсутствие namespace
из-за опасения, что имя User
может конфликтовать.
В этом случае, однако, вы можете использовать namespace
alias , как указано в вышеприведенных сообщениях
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);
Обратите внимание, что имена class
все User
, но в разных namespace
s. Цитирование PEP-20: Zen of Python:
Пространства имен - одна хорошая идея - позвольте сделать больше из них!
Надеюсь, что это поможет
Ответ 8
Можно ли перейти на использование интерфейса?
Возможно, вы могли бы создать интерфейс IColorScheme
, который реализуются всеми классами?
Это будет хорошо работать с шаблоном factory, как показано Крисом Марасти-Георгом
Ответ 9
Я добавляю этот комментарий для пользователей, которые находят это задолго до того, как OP примет свой "ответ".
Алиасирование в С# работает, указав имя класса, используя полное пространство имен. Один из них определяет имя псевдонима, которое можно использовать в пределах его области.
Пример.
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
}
}
Извините за быстро напечатанный код, но, надеюсь, он объяснит, как это должно быть реализовано, чтобы пользователи не вводили в заблуждение, полагая, что это невозможно сделать на С#.
Ответ 10
Это очень поздний частичный ответ - но если вы определите тот же класс "ColorScheme", в том же пространстве имен "Outlook", но в отдельных сборках, один из которых называется Outlook2003 и другой Outlook2007, тогда все, что вам нужно сделать, это ссылка соответствующая сборка.