Quero criar um alias para o nome de uma classe. A seguinte sintaxe seria perfeita:
public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
...
}
public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
mas não compilará.
Exemplo
Nota Este exemplo é fornecido apenas por conveniência. Não tente resolver esse problema específico sugerindo alterar o design de todo o sistema. A presença, ou falta, deste exemplo não altera a pergunta original.
Alguns códigos existentes dependem da presença de uma classe estática:
public static class ColorScheme
{
...
}
Este esquema de cores é o esquema de cores do Outlook 2003. quero apresentar um esquema de cores do Outlook 2007, mantendo o esquema de cores do Outlook 2003:
public static class Outlook2003ColorScheme
{
...
}
public static class Outlook2007ColorScheme
{
...
}
Mas ainda sou confrontado com o fato de que o código depende da presença de uma classe estática chamada ColorScheme
. Meu primeiro pensamento foi criar uma ColorScheme
classe que herdarei de Outlook2003
ou Outlook2007
:
public static class ColorScheme : Outlook2007ColorScheme
{
}
mas você não pode herdar de uma classe estática.
Meu próximo pensamento foi criar a ColorScheme
classe estática , mas fazer Outlook2003ColorScheme
e as Outlook2007ColorScheme
classes não estáticas. Então, uma variável estática na ColorScheme
classe estática pode apontar para qualquer esquema de cores "verdadeiro":
public static class ColorScheme
{
private static CustomColorScheme = new Outlook2007ColorScheme();
...
}
private class CustomColorScheme
{
...
}
private class Outlook2008ColorScheme : CustomColorScheme
{
...
}
private class Outlook2003ColorScheme : CustomColorScheme
{
...
}
mas isso exigiria que eu convertesse uma classe composta inteiramente de cores estáticas somente leitura em propriedades substituíveis e, em seguida, minha ColorScheme
classe precisaria ter os 30 getters de propriedade diferentes transformados no objeto contido.
Isso é muita digitação.
Então, meu próximo pensamento foi criar um alias para a classe:
public static ColorScheme = Outlook2007ColorScheme;
Mas isso não compila.
Como posso criar um alias para uma classe estática com outro nome?
Atualização: Alguém pode adicionar a resposta "Você não pode fazer isso em C #" , para que eu possa marcá-la como uma resposta aceita. Qualquer pessoa que deseje a resposta para a mesma pergunta encontrará esta pergunta, a resposta aceita e uma série de soluções alternativas que podem ou não ser úteis.
Eu só quero encerrar esta questão.
fonte
interface
, que todas as suas classes implementam. Conforme mencionado na resposta do chills42 . Você pode então definir um "serviço" ou "fábrica" que retorna um objeto que implementa aquela interface, dependendo das circunstâncias atuais (por exemplo, plataforma / SO) ou em um arquivo de configuração.Respostas:
Você não pode . A próxima melhor coisa que você pode fazer é ter
using
declarações nos arquivos que usam a classe.Por exemplo, você pode reescrever o código dependente usando um alias de importação (como um quase
typedef
substituto):using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Infelizmente, isso precisa entrar em cada escopo / arquivo que usa o nome.
Portanto, não sei se isso é prático no seu caso.
fonte
using
deve ser adicionado a todo código quebrado. E também nega o valor de ter um único alias, que me permite mudar todos os usuários daColorScheme
classe existente para usar uma nova classe - sem alterações. Em outras palavras: eu quero atribuir o alias daColorScheme
classe a outra classe.Você pode criar um alias para sua classe adicionando esta linha de código:
using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
fonte
Imports
. Estou errado?using
diretiva dentro de seu namespace, por exemplo, quando você precisa de um apelido de sua própria classe.Você deseja um ( Factory | Singleton ), dependendo de seus requisitos. A premissa é fazer com que o código do cliente não precise saber qual esquema de cores está recebendo. Se o esquema de cores deve ser amplo, um singleton deve servir. Se você pode usar um esquema diferente em circunstâncias diferentes, um padrão de fábrica é provavelmente o caminho a percorrer. De qualquer forma, quando o esquema de cores precisa ser alterado, o código só precisa ser alterado em um lugar.
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; } } }
fonte
Você não pode criar um alias para um nome de classe em C #.
Existem coisas que você pode fazer que não são o alias de um nome de classe em C #.
Mas, para responder à pergunta original: você não pode criar um alias para um nome de classe em C #.
Update: As pessoas estão confusas porque
using
não funciona. Exemplo: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 tudo funciona. Agora eu quero criar uma nova classe e um alias
ColorScheme
para ela (de modo que nenhum código precise ser modificado ):ColorScheme.cs
using ColorScheme = Outlook2007ColorScheme; class Outlook2007ColorScheme { public static Color ApplyColorScheme(Color c) { ... } }
Ohh, sinto muito. Este código não compila:
Minha pergunta era como criar um alias para uma classe em C #. Isso não pode ser feito. Existem coisas que posso fazer que não são o alias de um nome de classe em C #:
ColorScheme
parausing
ColorScheme
(solução alternativa de alteração de código porque não consigo apelido)ColorScheme
para usar um padrão de fábrica para uma classe polimórfica ou interface (solução alternativa de mudança de código porque eu não consigo apelido)Mas essas soluções alternativas envolvem quebrar o código existente: não é uma opção.
Se as pessoas dependem da presença de uma
ColorScheme
classe, tenho que realmente copiar / colar umaColorScheme
classe.Em outras palavras: não posso criar um alias para o nome de uma classe em C #.
Isso contrasta com outras linguagens orientadas a objetos, onde eu poderia definir o alias:
e eu estaria pronto.
fonte
tente isto:
using ColorScheme=[fully qualified].Outlook2007ColorScheme
fonte
Estou adicionando este comentário para usuários que acham isso muito depois de OP aceitar sua "resposta". Aliasing em C # funciona especificando o nome da classe usando seu namespace totalmente qualificado. Um definido, o nome do alias pode ser usado dentro de seu escopo. Exemplo.
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 } }
Pedimos desculpas pelo código digitado rapidamente, mas espero que ele explique como isso deve ser implementado para que os usuários não se enganem pensando que isso não pode ser feito em C #.
fonte
namespace Fully.Qualified.Namespace{
public class Example {
...public void DoStuff(){
...}
...}
}
.Criar apelidos da maneira que você gostaria de fazer não funcionará em C #. Isso ocorre porque o aliasing é feito por meio da
using
diretiva, que é limitada ao arquivo / espaço de nomes em questão. Se você tiver 50 arquivos que usam o nome da classe antiga, isso significará 50 lugares para atualizar.Dito isso, acho que há uma solução fácil para fazer a alteração do código o mínimo possível. Faça da
ColorScheme
classe uma fachada para suas chamadas para as classes reais com a implementação e use ousing
nesse arquivo para determinar qualColorScheme
você usa.Em outras palavras, faça o seguinte:
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); } }
Então, em seu code-behind, não mude nada:
private void button1_Click(object sender, EventArgs e) { this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor); }
Você pode então atualizar os valores de
ColorScheme
atualizando uma linha de código (using CurrentColorScheme = Outlook2008ColorScheme;
).Algumas preocupações aqui:
ColorScheme
classe e para aOutlook2007ColorScheme
classe. Isso é um trabalho extra, mas se for um código legado verdadeiro, não deve ser uma ocorrência frequente. Como um bônus, o códigoColorScheme
é tão simples que qualquer bug possível é muito óbvio.ColorScheme
classe que está substituindo, esta abordagem e qualquer outra pode ser um problema. Aconselho que você renomeie essa classe para algo comoColorSchemeOld
e, em seguida, acesse-a por meio deusing CurrentColorScheme = ColorSchemeOld;
.fonte
Suponho que você sempre pode herdar da classe base sem adicionar nada
public class Child : MyReallyReallyLongNamedClass {}
ATUALIZAR
Mas se você tiver a capacidade de refatorar o
class
próprio: Um nome de classe geralmente é desnecessariamente longo devido à falta denamespace
s.Se você vê casos como
ApiLoginUser
,DataBaseUser
,WebPortalLoginUser
, é geralmente indicação de falta denamespace
devido o medo de que o nomeUser
conflito força.Neste caso, entretanto, você pode usar um
namespace
apelido , como foi apontado nas postagens acimausing 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);
Observe como os
class
nomes são todosUser
, mas emnamespace
s diferentes . Citando PEP-20: Zen de Python :Espero que isto ajude
fonte
new
palavras-chave para esses métodos ou até mesmo criar seus próprios ExtensionMethods, certo? Em qualquer caso, é minha opinião forte que você deve sempre usar classes de coleção vanilla (ou seja, Dicionário, Lista, IEnumerable, IQueryable, etc.) com Modelos / ViewModels / POCOs personalizados. Como afirmaIColorScheme oColorScheme = ColorSchemeFactory.Create();
Além disso, você pode querer dar uma olhada em Injeção de dependênciaÉ possível mudar para uma interface?
Talvez você possa criar uma
IColorScheme
interface que todas as classes implementem?Isso funcionaria bem com o padrão de fábrica mostrado por Chris Marasti-Georg
fonte
É uma resposta parcial muito tardia - mas se você definir a mesma classe 'ColorScheme', no mesmo namespace 'Outlook', mas em assemblies separados, um chamado Outlook2003 e o outro Outlook2007, então tudo que você precisa fazer é referenciar o assembly apropriado .
fonte