在泛型中使用“using alias = class”怎么做?

126

有时我只想包含一个命名空间中的一个类,而不是整个命名空间,就像这个例子一样,我使用using语句为该类创建了别名:

using System;
using System.Text;
using Array = System.Collections.ArrayList;

我经常使用泛型来避免重复参数:

using LookupDictionary = System.Collections.Generic.Dictionary<string, int>;

现在我想用一个通用类型来实现同样的功能,同时保持它作为一个通用类型:

using List<T> = System.Collections.Generic.List<T>;

但是那样无法编译,那么有没有办法在保持类型为泛型的情况下创建这个别名呢?


我觉得这可能是 https://dev59.com/vnA65IYBdhLWcg3wogAb 的重复问题。 - Dan Tao
1
有一个开放的建议[#1239](https://github.com/dotnet/csharplang/issues/1239),涉及泛型类型和泛型类型约束别名。 - Pavel Anikhouski
2个回答

137

不,没有这样的东西。在C#中,类型别名必须是一个封闭的(也就是完全解析的)类型,因此不支持开放式泛型。

这在C#语言规范的9.4.1节中有所涉及。

  

使用别名可以为已构造的封闭类型命名,但不能为未绑定的泛型类型声明命名而不提供类型参数。

namespace N2
{
    using W = N1.A;         // Error, cannot name unbound generic type
    using X = N1.A.B;       // Error, cannot name unbound generic type
    using Y = N1.A<int>;    // Ok, can name closed constructed type
    using Z<T> = N1.A<T>;   // Error, using alias cannot have type parameters
}

1
使用别名指令不能在右侧具有开放式泛型类型。例如,您不能为List<T>创建使用别名,但可以为List<int>创建一个。http://msdn.microsoft.com/en-us/library/sf0df423.aspx - Sergey Mirvoda
6
虽然回答令人失望,但由于答案是正确且相关的,我仍会点赞。:-/ - BrainSlugs83
35
呜。C#让我非常想念C++的模板。而C++模板的错误信息则让我想念C#。 - Grault
在C# 12中是否仍然适用于"alias any type"?https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-12.0/using-alias-types - undefined

17

你可以按照http://msdn.microsoft.com/en-us/library/sf0df423.aspxhttp://msdn.microsoft.com/en-us/library/c3ay4x3d%28VS.80%29.aspx所示进行操作。

using gen = System.Collections.Generic;
using GenList = System.Collections.Generic.List<int>;

然后使用

gen::List<int> x = new gen::List<int>;
或者
GenList x = new GenList();

但是,您必须在每个使用它们的文件中使用定义来复制它们,因此,如果将来对它们进行更改并忘记在每个文件中更新,事情将会变得非常糟糕。

我希望未来的C#能够像处理扩展方法一样处理别名,并允许您在一个文件中定义许多别名,然后在其他地方使用,并在一个地方维护它们,同时为类型消费者隐藏内部不必要的类型映射细节。


13
有人提到,我知道这是一个旧讨论,但我刚遇到了同样的问题,搜索引擎把我带到了这里,那么这个讨论是否旧有何关系呢?我们是在报道新闻吗? - George Birbilis
4
我在Silverlight论坛上遇到更糟糕的行为 - 他们会删除旧讨论中的任何帖子。他们并没有真正理解人们会一次又一次地遇到这些问题,他们会进入只有部分信息的讨论,因为没有人在找到答案后添加一些心理提示。他们的借口是这会使旧讨论浮现在前面(好像没有更新的更好的答案或发展可以添加)。他们应该修复这样的论坛,以便在更新时不将非常陈旧的主题排到最前面,除非管理员将它们固定在顶部,而不是浪费我们的时间... - George Birbilis
10
因为回答没有帮助而被降低评分——所有展示的内容都已经在原始问题中声明过了,因此这个回答并不有用——实际上,这些知识是提出原始问题的必要先决条件。至于“旧讨论”方面的内容,我不确定它与问题有何关联,Stack Overflow 实际上奖励你参与旧的讨论——请参见“Necromancer”徽章。 - BrainSlugs83
2
@BrainSlugs83 我发现这个答案的第一部分很有帮助。1)OP没有提到使用别名导入命名空间作为选项(因此“所有显示的内容都已经声明”是不正确的陈述);2)间接导入“一个[通用]类型”而不会污染“所有命名空间”也是一种有效的选择;“缺点”是需要添加前缀,这是一个简单的权衡。使用别名还可以避免引入可能存在的扩展方法 - user2864740

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接