Как создать псевдоним имени класса В 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#", поэтому я могу отметить это как принятый ответ. Кто-нибудь еще хочет ответить на тот же вопрос найдет этот вопрос, принятый ответ и ряд обходных путей, которые могут быть или не быть полезными.



Я просто хочу закрыть этот вопрос.

689   10  
c#

10 ответов:

Если вы измените исходное имя класса, вы можете переписать зависимый код, используя псевдоним импорта как typedef заменить:

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

Это должно идти в верхней части файла / пространства имен, так же, как обычный using s.

Я не знаю, если это практично в вашем случае, хотя.

вы можете сделать псевдоним для вашего класса, добавив эту строку кода:

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

Ой, прости. Этот код не компилируется:

enter image description here

мой вопрос был как псевдоним класс В C#. Это невозможно сделать. Есть вещи, которые я могу сделать это не создание псевдонима для имени класса в C#:

  • изменить всех, кто зависит от ColorScheme до usingColorScheme вместо этого (обходной путь изменения кода, потому что я не могу псевдоним)
  • изменить всех, кто зависит от ColorScheme чтобы использовать заводской шаблон их полиморфный класс или интерфейс (обходной путь изменения кода, потому что я не могу псевдоним)

но эти обходные пути включают в себя нарушение существующего кода: не вариант.

если люди зависят от наличия ColorScheme класс, у меня на самом деле скопировать и вставить ColorScheme класса.

другими словами: Я не могу псевдоним имя класса В C#.

это контрастирует с другими объектно-ориентированными языками, где я мог бы определить псевдоним:

ColorScheme = Outlook2007ColorScheme

и я бы сделал.

попробуйте это:

using ColorScheme=[fully qualified].Outlook2007ColorScheme

сглаживание так, как вы хотели бы сделать это не будет работать в C#. Это происходит потому, что сглаживание выполняется через using директива, которая ограничена рассматриваемым файлом / пространством имен. Если у вас есть 50 файлов, которые используют старое название класса, это будет означать 50 мест для обновления.

тем не менее, я думаю, что есть простое решение, чтобы сделать ваш код изменить как можно меньше. Сделайте ColorScheme Class фасад для ваших вызовов к фактическим классам с реализацией, и используйте 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 само по себе: имя класса обычно излишне длинное из-за отсутствия namespace s.

если вы видите случаи как 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

    Ничего не найдено.