¿Cómo hago un alias con el nombre de una clase en C #, sin tener que agregar una línea de código a cada archivo que usa la clase?

StackOverflow https://stackoverflow.com/questions/244246

  •  04-07-2019
  •  | 
  •  

Pregunta

quiero crear un alias para un nombre de clase. La siguiente sintaxis sería perfecta:

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
   ...
}

public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;

pero no compilará.


Ejemplo

Nota Este ejemplo se proporciona solo para conveniencia. No intente resolver este problema en particular sugiriendo cambiar el diseño de todo el sistema. La presencia o falta de este ejemplo no cambia la pregunta original.

Algunos códigos existentes dependen de la presencia de una clase estática:

public static class ColorScheme
{
   ...
}

Este esquema de color es el esquema de color de Outlook 2003. Quiero introducir una combinación de colores de Outlook 2007, a la vez que conservo la combinación de colores de Outlook 2003:

public static class Outlook2003ColorScheme
{
   ...
}

public static class Outlook2007ColorScheme
{
   ...
}

Pero todavía estoy ante el hecho de que el código depende de la presencia de una clase estática llamada ColorScheme. Mi primer pensamiento fue crear una clase ColorScheme que descenderé de Outlook2003 o Outlook2007:

public static class ColorScheme : Outlook2007ColorScheme
{
}

pero no puedes descender de una clase estática.

Mi siguiente pensamiento fue crear la clase estática ColorScheme, pero hacer que las clases Outlook2003ColorScheme y Outlook2007ColorScheme no sean estáticas. Luego, una variable estática en la clase ColorScheme estática puede apuntar a " true " esquema de color:

public static class ColorScheme
{
    private static CustomColorScheme = new Outlook2007ColorScheme();
    ...
}

private class CustomColorScheme 
{ 
   ...
}

private class Outlook2008ColorScheme : CustomColorScheme 
{
    ...
}

private class Outlook2003ColorScheme : CustomColorScheme 
{
   ...
}

pero eso requeriría que yo convirtiera una clase compuesta completamente de Colores estáticos de solo lectura en propiedades reemplazables, y luego mi clase ColorScheme tendría que tener a los 30 captadores de propiedades diferentes derrotados en el objeto contenido.

Eso es demasiado escribir.

Así que mi siguiente pensamiento fue alias la clase:

public static ColorScheme = Outlook2007ColorScheme;

Pero eso no se compila.

¿Cómo puedo alias una clase estática con otro nombre?


Actualización: ¿Puede alguien agregar la respuesta " No puede hacer esto en C # " , para que pueda marcarla como la respuesta aceptada. Cualquier otra persona que desee la respuesta a la misma pregunta encontrará esta pregunta, la respuesta aceptada y una serie de soluciones que podrían, o no, ser útiles.

Solo quiero cerrar esta pregunta.

¿Fue útil?

Solución 4

No puede asignar un alias a un nombre de clase en C #.

Hay cosas que puedes hacer que no son alias de un nombre de clase en C #.

Pero para responder a la pregunta original: no puede asignar un alias al nombre de una clase en C #.


Actualización: La gente está confundida porque el uso no funciona. Ejemplo:

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

Y todo funciona. Ahora quiero crear una clase nueva y alias ColorScheme (para que no sea necesario modificar el código ):

ColorScheme.cs

using ColorScheme = Outlook2007ColorScheme;

class Outlook2007ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}

Ohh, lo siento. Este código no se compila:

ingrese la descripción de la imagen aquí

Mi pregunta era cómo alias una clase en C #. No se puede hacer. Hay cosas que puedo hacer que son no aliasing un nombre de clase en C #:

  • cambiar a todos los que dependen de ColorScheme a usando ColorScheme en su lugar (solución al cambio de código porque no puedo hacer un alias)
  • cambie a todos los que dependen de ColorScheme para usar un patrón de fábrica, una clase o interfaz polimórfica (solución de cambio de código porque no puedo hacer un alias)

Pero estas soluciones implican romper el código existente: no es una opción.

Si las personas dependen de la presencia de una clase ColorScheme , tengo que copiar / pegar una clase ColorScheme .

En otras palabras: no puedo alias un nombre de clase en C #.

Esto contrasta con otros lenguajes orientados a objetos, donde podría definir el alias:

ColorScheme = Outlook2007ColorScheme

y ya habré terminado.

Otros consejos

Si cambia el nombre de la clase original, puede volver a escribir el código dependiente utilizando un alias de importación como un typedef sustituto:

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

Esto tiene que ir a la parte superior del archivo / espacio de nombres, al igual que usando s.

No sé si esto es práctico en tu caso, sin embargo.

Puedes crear un alias para tu clase agregando esta línea de código:

using Outlook2007ColorScheme = YourNameSpace.ColorScheme;

Quieres una ( Factory | Singleton ), dependiendo de sus requisitos. La premisa es hacerlo de modo que el código del cliente no tenga que saber qué esquema de color está obteniendo. Si el esquema de color debe ser de aplicación, un singleton debería estar bien. Si puede usar un esquema diferente en diferentes circunstancias, un patrón de Fábrica es probablemente el camino a seguir. De cualquier manera, cuando el esquema de color necesita cambiar, el código solo se debe cambiar en un 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; }
    }
}

prueba esto:

using ColorScheme=[fully qualified].Outlook2007ColorScheme

Estoy agregando este comentario para los usuarios que encuentren esto mucho tiempo después de que OP aceptó su " respuesta " ;. El alias en C # funciona especificando el nombre de la clase utilizando su espacio de nombres completo. Una definida, el nombre de alias se puede usar dentro de su alcance. Ejemplo.

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
  }

}

Pido disculpas por el código escrito rápidamente, pero espero que explique cómo se debe implementar esto para que los usuarios no engañen creyendo que no se puede hacer en C #.

Aliasing la forma en que le gustaría hacerlo no funcionará en C #. Esto se debe a que el aliasing se realiza a través de la directiva using , que se limita al archivo / espacio de nombres en cuestión. Si tiene 50 archivos que usan el nombre de clase anterior, eso significará 50 lugares para actualizar.

Dicho esto, creo que hay una solución fácil para hacer que su código cambie lo más mínimo posible. Convierta la clase ColorScheme en una fachada para sus llamadas a las clases reales con la implementación, y use el usando en ese archivo para determinar qué ColorScheme utilizar.

En otras palabras, haz esto:

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);
   }
}

Luego, en tu código detrás, no cambies nada:

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}

Luego puede actualizar los valores de ColorScheme actualizando una línea de código ( usando CurrentColorScheme = Outlook2008ColorScheme; ).

Un par de preocupaciones aquí:

  • Cada nuevo método o definición de propiedad deberá agregarse en dos lugares, a la clase ColorScheme ya la clase Outlook2007ColorScheme . Esto es un trabajo adicional, pero si este es un verdadero código heredado, no debería ser una ocurrencia frecuente. Como beneficio adicional, el código en ColorScheme es tan simple que cualquier posible error es muy obvio.
  • Este uso de clases estáticas no me parece natural; Probablemente trataría de refactorizar el código heredado para hacer esto de manera diferente, pero también entiendo que su situación puede no permitirlo.
  • Si ya tiene una clase de ColorScheme que está reemplazando, este enfoque y cualquier otro podría ser un problema. Le aconsejaría que cambie el nombre de esa clase a algo como ColorSchemeOld , y luego acceda a ella a través de utilizando CurrentColorScheme = ColorSchemeOld; .

Supongo que siempre se puede heredar de la clase base sin agregar nada

public class Child : MyReallyReallyLongNamedClass {}

UPDATE

Pero si tiene la capacidad de refactorizar la propia class : un nombre de clase suele ser innecesariamente largo debido a la falta de espacio de nombres s.

Si ve casos como ApiLoginUser , DataBaseUser , WebPortalLoginUser , suele indicar la falta de espacio de nombres debido el temor de que el nombre Usuario pueda entrar en conflicto.

Sin embargo, en este caso, puede utilizar el alias namespace alias , como se ha señalado en las publicaciones anteriores

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);

Observe cómo los nombres de class son todos User , pero en diferentes namespace s. Citando PEP-20: Zen of Python :

  

Los espacios de nombres son una gran idea, ¡vamos a hacer más de ellos!

Espero que esto ayude

¿Es posible cambiar a usar una interfaz?

¿Quizás podrías crear una interfaz IColorScheme que implementen todas las clases?

Esto funcionaría bien con el patrón de fábrica como lo muestra Chris Marasti-Georg

Es una respuesta parcial muy tardía, pero si define la misma clase 'ColorScheme', en el mismo espacio de nombres 'Outlook', pero en ensamblajes separados, uno llamado Outlook2003 y el otro Outlook2007, todo lo que necesita hacer es referencia la asamblea apropiada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top