如何在C#中为类名设置别名,而不必为每个使用该类的文件添加一行代码?

Ian*_*oyd 71 c# class-design

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

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
   ...
}

public class MyName = LongClassNameOrOneThatContainsVersionOrDomainSpecificName;
Run Code Online (Sandbox Code Playgroud)

但它不会编译.


注意此示例仅供参考.不要试图通过建议改变整个系统的设计来解决这个特殊问题.此示例的存在或缺乏不会改变原始问题.

一些现有代码依赖于静态类的存在:

public static class ColorScheme
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

此配色方案是Outlook 2003配色方案.我想介绍一个Outlook 2007配色方案,同时保留Outlook 2003配色方案:

public static class Outlook2003ColorScheme
{
   ...
}

public static class Outlook2007ColorScheme
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

但我仍然面临这样一个事实,即代码依赖于名为ColorScheme的静态类的存在.我的第一个想法是创建一个ColorScheme类,我将从Outlook2003或Outlook2007下载:

public static class ColorScheme : Outlook2007ColorScheme
{
}
Run Code Online (Sandbox Code Playgroud)

但你不能从静态类下降.

我的下一个想法是创建静态ColorScheme类,但使Outlook2003ColorScheme和Outlook2007ColorScheme类非静态.然后静态ColorScheme类中的静态变量可以指向"true"颜色方案:

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

private class CustomColorScheme 
{ 
   ...
}

private class Outlook2008ColorScheme : CustomColorScheme 
{
    ...
}

private class Outlook2003ColorScheme : CustomColorScheme 
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

但这需要我将一个由只读静态颜色组成的类转换为可覆盖的属性,然后我的ColorScheme类需要将30个不同的属性getter thunk down到包含的对象中.

打字太多了.

所以我的下一个想法是给这个类别名:

public static ColorScheme = Outlook2007ColorScheme;
Run Code Online (Sandbox Code Playgroud)

但那不编译.

我如何将静态类别名改为另一个名称?


更新:有人可以添加答案"你不能在C#中做到这一点",所以我可以将其标记为已接受的答案.任何想要回答相同问题的人都会发现这个问题,接受的答案以及可能会或可能不会有用的一些变通方法.

我只想关闭这个问题.

Kon*_*lph 112

如果更改原始类名,则可以使用导入别名作为typedef替代来重写从属代码:

using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;
Run Code Online (Sandbox Code Playgroud)

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

不过,我不知道这是否适用于你的情况.

  • 如果它可以位于包含原始类的文件的顶部:它会很棒.但必须将`using`添加到所有损坏的代码中.并且它还否定了具有单个别名的价值,这使我可以将现有`ColorScheme`类的所有用户切换为使用新类 - 无需更改.换句话说:我想将`ColorScheme`类别名为另一个类. (6认同)

moh*_*edn 22

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

using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
Run Code Online (Sandbox Code Playgroud)

  • 你需要Fully.Qualified.Namespace.Of.ColorScheme (5认同)

Chr*_*org 13

你需要一个(工厂 | 单身),这取决于你的要求.前提是使客户端代码不必知道它获得的颜色方案.如果配色方案应该是应用程序范围的,单身就应该没问题.如果您可以在不同的情况下使用不同的方案,那么工厂模式可能就是您的选择.无论哪种方式,当颜色方案需要改变时,代码只需要在一个地方改变.

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ian*_*oyd 11

您不能在C#中为类名别名.

有些事情你可以做的不是在C#中别名类名.

但回答最初的问题:你不能在C#中为别名命名别名.


更新:人们很困惑为什么using不工作.例:

Form1.cs的

private void button1_Click(object sender, EventArgs e)
{
   this.BackColor = ColorScheme.ApplyColorScheme(this.BackColor);
}
Run Code Online (Sandbox Code Playgroud)

ColorScheme.cs

class ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}
Run Code Online (Sandbox Code Playgroud)

一切正常.现在我想创建一个类,并为它创建别名 ColorScheme(这样就不需要修改代码):

ColorScheme.cs

using ColorScheme = Outlook2007ColorScheme;

class Outlook2007ColorScheme
{
    public static Color ApplyColorScheme(Color c) { ... }
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

我的问题是如何别名在C#中的一类.它无法完成.我可以做的事情不是在C#中别名类名:

  • 改变大家谁依赖于ColorSchemeusing ColorScheme代替(代码变化的解决方法,因为我无法别名)
  • 改变依赖于ColorScheme使用工厂模式的每个人他们的多态类或接口(代码更改解决方法因为我不能别名)

但这些变通办法涉及破坏现有代码:不是一种选择.

如果人们依赖于ColorScheme类的存在,我必须实际复制/粘贴一个ColorScheme类.

换句话说:我不能在C#中为类名别名.

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

ColorScheme = Outlook2007ColorScheme
Run Code Online (Sandbox Code Playgroud)

我会完成的.

  • 你绝对可以在C#中为别名命名别名."using <alias_name> = <fully_qualified_name>;" (14认同)
  • Downvote - 你已经说过"你不能在C#中使用别名别名." 您可以.你不能做的是按照你想要的方式别名一个类 - 这是一个非常合理的要求,但你的陈述是不正确的. (10认同)
  • 正如几张海报所指出的那样,不得不使用限定名称来禁止别名.你**可以**别名.您只需使用完全限定名称即可.您可能会觉得这很不方便,但它并没有使"您不能在C#中使用别名别名"这句话为真.也许在C#中混叠的方式与您期望的不同.那没关系 - 如果是这样的话,说明一下.但是你可以**在C#中使用别名,因为规范声明你可以根据它提供的定义这样做. (8认同)
  • LIke @clemahieu说,你绝对可以别名一个类名,你只需要使用完全限定名.此外,如果别名是泛型类,则必须添加泛型类限定符.例如:使用ShortName = MyNamespace.SubNamespace.GenericClass <MyType>; (5认同)
  • 我喜欢程序员如何在行之间进行语句.Ian真正说的是C#是愚蠢而破碎的,因为它不能做任何人想做的应该做的简单基本的事情.他是对的 - 无论具体的语义是否让你开心. (4认同)
  • @汤姆W+1。从 MSDN 库 [using 指令(C# 参考)](http://msdn.microsoft.com/en-us/library/sf0df423(v=vs.110).aspx)(引用): *using* 指令有两种用途: 1) 允许在命名空间中使用类型,这样您就不必限定该命名空间中类型的使用;2) 为命名空间**或类型**创建别名**。这称为*using 别名指令*。 (2认同)
  • @informatik01 人们似乎对我使用术语 *alias* 来描述创建 *transparent* 别名非常不满。请建议一个除 *"alias"* 之外的术语,它描述了创建一个 *"transparent"* 别名。那么我们可以同意 C# 不能创建别名。 (2认同)
  • @IQpierce 我认为您将强类型与“损坏”混淆了。仅仅因为一种语言不是鸭子类型的,并不会让它坏掉。有些人会反其道而行之。这只是取决于你喜欢什么。 (2认同)
  • Ian 认为您不必总是使用 FQName。更仔细地阅读。Ian 正确而明确地指出,“使用”创建某种别名的方法不会创建“真正的”别名,因为*它会破坏现有代码*。真正的类别名的行为与它背后的真实类完全相同,并且不需要触及现有代码。当我发现这个问题时,我正在寻找一种在不破坏现有代码的情况下声明别名的方法。拥有这将是一件很棒的事情。 (2认同)
  • 我终于意识到这里的困惑在于,当 Ian 说“别名”时,他的意思是“我不想在引用文件中放置**任何东西**”。但是任何熟悉“别名”的 C# 定义的人都会立即想到这种方法,它是每个文件顶部的一个合适的“using”语句。这是两种不同的混叠方法。Ian 想要的会更方便,因为您不必接触所有这些文件。(如果您没有这些文件的源代码,则在 C# 中根本不可能。) (2认同)

dpu*_*ton 10

试试这个:

using ColorScheme=[fully qualified].Outlook2007ColorScheme
Run Code Online (Sandbox Code Playgroud)

  • 您需要Fully.Qualified.Namespace.Of.ColorScheme (2认同)

J-A*_*ano 6

我正在为在 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
  }

}
Run Code Online (Sandbox Code Playgroud)

对快速输入的代码表示歉意,但希望它解释了应该如何实现,以便用户不会误认为它不能在 C# 中完成。

  • 需要明确的是,这与伊恩所寻求的不同。Ian 遇到一种情况,他无法(或不想)更改引用类的源文件。他想要一种方法**在他的应用程序或库中的一个地方**进行更改,从而产生一个具有所需名称的类,所有其他代码都可以使用它[无需添加“使用”对多个源文件的声明 - 例如该源可能无法更改]。 (2认同)

Rez*_*eza 5

从 C# 10 开始,您可以使用全局 using。

global using Short = LongClassNameOrOneThatContainsVersionsOrDomainSpecificName;
Run Code Online (Sandbox Code Playgroud)

如果你想在 MVC 视图中使用它,你可以将 using 行添加到 _viewImports.cshtml 中。

全局 using 指令是最近在 C# 版本 10.0 中添加到 C# 语言中的一项新功能。此功能允许开发人员在项目中的任何一个文件中全局声明命名空间,并且全局声明的命名空间将被导入并可供应用程序中的所有文件使用。(c-尖角