Как создать псевдоним имени класса В C#?
Я хочу создать псевдоним для имени класса. Следующий синтаксис был бы идеальным:
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 нестатическими. Тогда статическая переменная в классе static ColorScheme может указывать на любую" истинную " цветовую схему:
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
но это потребует от меня преобразования класса, состоящего полностью из статических цветов только для чтения, в переопределяемые свойства, а затем мой класс ColorScheme должен будет иметь 30 различных свойства геттеров преобразователь в содержащихся в нем объектов.
это просто слишком много печатать.
так что моя следующая мысль была псевдоним класса:
public static ColorScheme = Outlook2007ColorScheme;
но это не компиляции.
как я могу псевдоним статического класса в другое имя?
обновление: может кто-нибудь добавить ответ "вы не можете сделать это в C#", поэтому я могу отметить это как принятый ответ. Кто-нибудь еще хочет ответить на тот же вопрос найдет этот вопрос, принятый ответ и ряд обходных путей, которые могут быть или не быть полезными.
Я просто хочу закрыть этот вопрос.
10 ответов:
Если вы измените исходное имя класса, вы можете переписать зависимый код, используя псевдоним импорта как
typedefзаменить:using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;Это должно идти в верхней части файла / пространства имен, так же, как обычный
usings.Я не знаю, если это практично в вашем случае, хотя.
вы можете сделать псевдоним для вашего класса, добавив эту строку кода:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
вы хотите a (завод/Синглтон), в зависимости от ваших потребностей. Предпосылка состоит в том, чтобы сделать это так, чтобы клиентский код не должен был знать, какую цветовую схему он получает. Если цветовая схема должна быть широкой, синглтон должен быть прекрасным. Если вы можете использовать другую схему в разных обстоятельствах, Заводской шаблон, вероятно,путь. В любом случае, когда цветовая схема должна быть изменена, код должен быть изменен только в одном случае место.
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; } } }
вы не можете псевдоним имя класса В C#.
есть вещи, которые вы можете сделать, не сглаживая имя класса В C#.
но, чтобы ответить на исходный вопрос: вы не псевдоним, а имя класса в C#.
обновление: люди не понимают, почему
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) { ... } }Ой, прости. Этот код не компилируется:
мой вопрос был как псевдоним класс В C#. Это невозможно сделать. Есть вещи, которые я могу сделать это не создание псевдонима для имени класса в C#:
- изменить всех, кто зависит от
ColorSchemeдоusingColorSchemeвместо этого (обходной путь изменения кода, потому что я не могу псевдоним)- изменить всех, кто зависит от
ColorSchemeчтобы использовать заводской шаблон их полиморфный класс или интерфейс (обходной путь изменения кода, потому что я не могу псевдоним)но эти обходные пути включают в себя нарушение существующего кода: не вариант.
если люди зависят от наличия
ColorSchemeкласс, у меня на самом деле скопировать и вставитьColorSchemeкласса.другими словами: Я не могу псевдоним имя класса В C#.
это контрастирует с другими объектно-ориентированными языками, где я мог бы определить псевдоним:
ColorScheme = Outlook2007ColorSchemeи я бы сделал.
сглаживание так, как вы хотели бы сделать это не будет работать в C#. Это происходит потому, что сглаживание выполняется через
usingдиректива, которая ограничена рассматриваемым файлом / пространством имен. Если у вас есть 50 файлов, которые используют старое название класса, это будет означать 50 мест для обновления.тем не менее, я думаю, что есть простое решение, чтобы сделать ваш код изменить как можно меньше. Сделайте
ColorSchemeClass фасад для ваших вызовов к фактическим классам с реализацией, и используйте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;.
Я предполагаю, что вы всегда можете наследовать от базового класса ничего не добавил
public class Child : MyReallyReallyLongNamedClass {}обновление
но если у вас есть возможность рефакторинга
classсамо по себе: имя класса обычно излишне длинное из-за отсутствияnamespaces.если вы видите случаи как
ApiLoginUser,DataBaseUser,WebPortalLoginUser, обычно является признаком отсутствияnamespaceиз-за страха, что названиеUserможет возникнуть конфликт.в этом случае, однако, вы можете использовать
namespaceпсевдоним ,как было указано выше, в должности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ы. Цитирую PEP-20: Zen of Python:пространства имен-это одна отличная идея-давайте сделаем больше из них!
надеюсь, что это помогает
Я добавляю этот комментарий для пользователей, которые находят это долго после того, как OP принял их "ответ". Сглаживание в C# работает путем указания имени класса, используя его полное пространство имен. Один определен, имя псевдонима может использоваться в его области. Образец.
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 } }извиняюсь за быстро набранный код, но, надеюсь, он объясняет, как это должно быть реализовано, чтобы пользователи не вводили в заблуждение, полагая, что это невозможно сделать в C#.
можно ли перейти на использование интерфейса?
возможно, вы могли бы создать
IColorSchemeинтерфейс, который реализуют все классы?Это будет хорошо работать с заводским рисунком, как показано Крисом Марасти-Георгом
Это очень поздний частичный ответ - но если вы определяете тот же класс 'ColorScheme', в том же пространстве имен 'Outlook', но в отдельных сборках, одна называется Outlook2003, а другая Outlook2007, то все, что вам нужно сделать, это ссылаться на соответствующую сборку.

Comments