100

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

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我将从Outlook2003or继承的类Outlook2007

public static class ColorScheme : Outlook2007ColorScheme
{
}

但是您不能从静态类继承。

我的下一个想法是创建静态ColorScheme类,但使Outlook2003ColorSchemeOutlook2007ColorScheme类非静态。然后静态类中的静态变量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# 中执行此操作”,因此我可以将其标记为已接受的答案。任何其他想要相同问题答案的人都会发现这个问题、已接受的答案以及许多可能有用或可能没有用的变通方法。

我只想结束这个问题。

4

11 回答 11

144

你不能您可以做的下一件最好的事情是using在使用该类的文件中声明。

例如,您可以使用导入别名(作为准typedef替代)重写依赖代码:

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

不幸的是,这需要进入使用该名称的每个范围/文件。

因此,我不知道这在您的情况下是否实用。

于 2008-10-28T18:12:02.990 回答
25

你可以通过添加这行代码为你的类创建一个别名:

using Outlook2007ColorScheme = YourNameSpace.ColorScheme;
于 2008-10-28T18:19:52.460 回答
15

您不能在 C# 中为类名设置别名。

在 C# 中,您可以做一些不为类名起别名的事情。

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


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

Form1.cs

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

颜色方案.cs

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

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

颜色方案.cs

using ColorScheme = Outlook2007ColorScheme;

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

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

在此处输入图像描述

我的问题是如何在 C# 中给类起别名。这是不可能的。我可以做的一些事情不是在 C# 中为类名起别名:

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

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

如果人们依赖于ColorScheme课程的存在,我必须实际复制/粘贴ColorScheme课程。

换句话说:我不能在 C# 中给类名起别名。

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

ColorScheme = Outlook2007ColorScheme

我就完了。

于 2009-01-12T19:08:57.380 回答
12

根据您的要求,您想要一个(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; }
    }
}
于 2008-10-28T18:15:34.043 回答
11

试试这个:

using ColorScheme=[fully qualified].Outlook2007ColorScheme
于 2008-10-28T18:12:59.917 回答
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# 中完成。

于 2017-11-21T18:23:16.733 回答
4

在 C# 中,按照您想要的方式进行别名化将不起作用。这是因为别名是通过using指令完成的,该指令仅限于相关的文件/命名空间。如果您有 50 个使用旧类名的文件,则意味着要更新 50 个位置。

也就是说,我认为有一个简单的解决方案可以使您的代码更改尽可能少。使ColorScheme该类成为您调用具有实现的实际类的外观,并使用该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;.
于 2015-02-28T22:08:49.987 回答
3

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

public class Child : MyReallyReallyLongNamedClass {}

更新

但是如果你有重构class自身的能力:由于缺少namespaces,类名通常不必要地长。

如果您将案例视为ApiLoginUser, DataBaseUser, WebPortalLoginUser, 通常表示namespace由于担心名称User可能会发生冲突而缺乏。

但是,在这种情况下,您可以使用namespacealias ,正如上面的帖子中所指出的那样

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名称是 all User,但在不同namespace的 s 中。引用PEP-20:Python 之禅

命名空间是一个很棒的想法——让我们做更多的事情!

希望这可以帮助

于 2015-06-25T23:56:49.477 回答
2

是否可以更改为使用接口?

也许您可以创建一个IColorScheme所有类都实现的接口?

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

于 2008-10-28T18:18:27.703 回答
0

这是一个非常晚的部分答案 - 但是如果您在相同的命名空间“Outlook”中定义相同的类“ColorScheme”,但在单独的程序集中,一个称为 Outlook2003,另一个称为 Outlook2007,那么您需要做的就是引用适当的程序集.

于 2015-08-31T15:53:34.560 回答
0

我发现在 C# 中模拟别名的最佳方法是继承。

创建一个继承自原始类的新类:

public class LongClassNameOrOneThatContainsVersionsOrDomainSpecificName
{
   ...
}

public class MyName 
    : LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{

}

唯一需要注意的是构造函数。您需要为MyName类提供一个构造函数。

public class MyName 
    : LongClassNameOrOneThatContainsVersionOrDomainSpecificName
{
    public MyName(T1 param1, T2 param2) : base(param1, param2) {}   
}

在此示例中,我使用T1andT2作为泛型类型,因为我不知道您的LongClassNameOrOneThatContainsVersionOrDomainSpecificName类的构造函数。

但请注意,这不是 alias。对您的应用程序执行此操作可能会遇到一些问题。您可能需要创建一些额外的代码来检查类型,甚至重载一些运算符。

于 2021-05-29T13:09:52.707 回答