代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

如何在C_中为类名命名,而不必向使用该类的每个文件添加一行代码?

  •  62
  • Ian Boyd  · 技术社区  · 16 年前

    我想为类名创建一个别名。以下语法将是完美的:

    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类非静态。然后,静态配色方案类中的静态变量可以指向“真”配色方案:

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

    但这需要我将一个由只读静态颜色组成的类转换为可重写的属性,然后我的colorScheme类需要将30个不同的属性getter转换为包含的对象。

    打字太多了。

    所以我的下一个想法是给班级取别名:

    public static ColorScheme = Outlook2007ColorScheme;
    

    但这并不能编译。

    如何将静态类别名为其他名称?


    更新: 有人能加上答案吗 “你不能用C来做这件事。” ,所以我可以将其标记为接受的答案。任何其他想要回答同一个问题的人都会发现这个问题、公认的答案以及一些可能有用或不有用的解决方法。

    我只想结束这个问题。

    10 回复  |  直到 6 年前
        1
  •  108
  •   Konrad Rudolph    16 年前

    如果更改原始类名,可以使用导入别名作为 typedef 替代品:

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

    这必须放在文件/命名空间的顶部,就像常规的 using S.

    不过,我不知道这在你的情况下是否可行。

        2
  •  20
  •   mohammedn    11 年前

    通过添加以下代码行,可以为类创建别名:

    using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
    
        3
  •  12
  •   Chris Marasti-Georg Scott Weinstein    16 年前

    你想要一个 Factory γ Singleton )根据您的要求。前提是要让客户机代码不必知道它得到的是哪种颜色方案。如果配色方案应适用范围广,则单件就可以了。如果您可以在不同的情况下使用不同的方案,那么工厂模式可能就是解决问题的方法。不管怎样,当配色方案需要更改时,代码只能在一个地方更改。

    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; }
        }
    }
    
        4
  •  10
  •   Ian Boyd    13 年前

    不能在C中为类名加别名。

    您可以这样做,而不是在C中为类名添加别名。

    但要回答最初的问题:您不能在C中为类名加别名。


    更新: 人们很困惑为什么 using 不起作用。例子:

    格式1.CS

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

    彩色图解

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

    一切正常。现在我想创建一个 新的 类,以及 别名 ColorScheme 对它(这样) 无需修改代码 ):

    彩色图解

    using ColorScheme = Outlook2007ColorScheme;
    
    class Outlook2007ColorScheme
    {
        public static Color ApplyColorScheme(Color c) { ... }
    }
    

    哦,对不起。此代码无法编译:

    enter image description here

    我的问题是如何 别名 C类中的一个类。这是不可能的。我可以做的事情是 在C中为类名添加别名:

    • 改变所有依赖的人 配色方案 使用 配色方案 相反(代码更改解决方案,因为我不能使用别名)
    • 改变所有依赖的人 配色方案 要使用工厂模式,可以使用多态类或接口(代码更改解决方案,因为我不能使用别名)

    但是这些解决方法涉及到破坏现有代码:不是一个选项。

    如果人们依赖于 配色方案 类,我必须实际复制/粘贴 配色方案 班级。

    换句话说:我不能用C作为类名的别名。

    这与其他面向对象的语言形成了对比,在这里我可以定义别名:

    ColorScheme = Outlook2007ColorScheme
    

    我就完了。

        5
  •  10
  •   Ian Boyd    13 年前

    试试这个:

    using ColorScheme=[fully qualified].Outlook2007ColorScheme
    
        6
  •  3
  •   Timothy    10 年前

    以您希望的方式创建别名在C中不起作用。这是因为别名是通过 using 指令,仅限于相关文件/命名空间。如果有50个文件使用旧类名,则意味着需要更新50个位置。

    也就是说,我认为有一个简单的解决方案可以使代码更改尽可能少。使 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);
    }
    

    然后可以更新 配色方案 通过更新一行代码( using CurrentColorScheme = Outlook2008ColorScheme; )

    这里有几个问题:

    • 然后需要将每个新方法或属性定义添加到 配色方案 班级和 Outlook2007ColorScheme 班级。这是额外的工作,但如果这是真正的遗留代码,就不应该频繁出现。作为奖励,代码 配色方案 非常简单,任何可能的错误都非常明显。
    • 对我来说,静态类的这种使用似乎并不自然;我可能会尝试重构遗留代码来实现这一点,但我也理解,您的情况可能不允许这样做。
    • 如果你已经有了 配色方案 您要替换的类,此方法和任何其他方法都可能是一个问题。我建议您将该类重命名为 ColorSchemeOld ,然后通过 using CurrentColorScheme = ColorSchemeOld; .
        7
  •  3
  •   percebus    8 年前

    我想您总是可以从基类继承而不添加任何内容

    public class Child : MyReallyReallyLongNamedClass {}
    

    更新

    但是如果您有能力重构 class 本身:由于缺少 namespace S.

    如果你将案例视为 ApiLoginUser , DataBaseUser , WebPortalLoginUser ,通常表示缺少 命名空间 因为害怕这个名字 User 可能会发生冲突。

    但是,在这种情况下,您可以使用 命名空间 别名 如上文所述

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

    注意如何 名字都是 用户 但是在不同的 命名空间 美国报价 PEP-20: Zen of Python :

    名称空间是一个非常好的主意——让我们做更多的事情吧!

    希望这有帮助

        8
  •  3
  •   J-Americano    7 年前

    我要为那些在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中完成。

        9
  •  2
  •   Ian Boyd    13 年前

    是否可以改为使用接口?

    也许你可以创造一个 IColorScheme 所有类实现的接口?

    这与Chris Marasti Georg所示的工厂模式很好地配合。

        10
  •  0
  •   Mark Farmiloe    9 年前

    这是一个非常晚的部分答案——但是如果您在同一个命名空间“outlook”中定义了同一个类“colorScheme”,但是在不同的程序集中,一个程序集称为outlook2003,另一个程序集称为outlook2007,那么您需要做的就是引用适当的程序集。