【问题标题】:Using Statement with Generics: using ISet<> = System.Collections.Generic.ISet<>使用泛型语句:使用 ISet<> = System.Collections.Generic.ISet<>
【发布时间】:2010-09-15 17:40:56
【问题描述】:

由于我使用了两个不同的通用集合命名空间(System.Collections.GenericIesi.Collections.Generic),因此我遇到了冲突。在项目的其他部分,我同时使用 nunit 和 mstest 框架,但是当我调用 Assert 时,我想通过

使用 nunit 版本
using Assert = NUnit.Framework.Assert;

这很好用,但我想对泛型类型做同样的事情。但是,以下几行不起作用

using ISet = System.Collections.Generic.ISet;
using ISet<> = System.Collections.Generic.ISet<>;

有谁知道如何告诉 .net 如何将 using 语句与泛型一起使用?

【问题讨论】:

  • 这是一个偶尔需要的功能。长期以来,它一直在可能的功能列表中,但从未得到足够高的优先级来实际实施。
  • Eric,这是我第一次遇到这个问题,因为 .net 4.0 框架添加了 ISet,并且 Iesi.Collections dll 以 3.5 为目标。通常,其他开发人员会很好地避免与标准 .net 命名发生冲突。
  • 为什么将它放在两个不同的命名空间中?你能提供更多信息吗?
  • 我会换一种说法。故意为两个不同的事物使用相同的名称会很不方便。如果您极不可能同时成为 using 两个命名空间,则此方法效果最佳。
  • @EricLippert 从 Java 或 Haskell 或其他支持精确符号导入的语言(即 Java 中的 import myModule.MyClass;)转换代码时,我发现这是 C# 的一个主要缺陷,因为你必须 using 一切来自System.Collections.Generic,即使您的LINQ 表达式只需要IEnumerable&lt;&gt;。Java 不允许重命名,但我认为导入重命名实际上是“偶尔”请求的,而不是精确的导入/使用。

标签: c# generics syntax alias using


【解决方案1】:

不幸的是,using 指令不能满足您的要求。你可以说:

using Frob = System.String;

using ListOfInts = System.Collections.Generic.List<System.Int32>;

但你不能说

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

using Blob = System.Collections.Generic.List

这是语言的一个缺点,从来没有被纠正过。

【讨论】:

  • 最好的游说方式是什么?
  • @miniBill:尝试在 Roslyn.codeplex.com 的语言设计论坛发帖。
  • 有一个提案here。我也很想拥有这个功能。
【解决方案2】:

我认为你最好给命名空间本身加上别名而不是泛型类型(我认为这是不可能的)。

例如:

using S = System.Collections.Generic;
using I = Iesi.Collections.Generic;

那么对于 BCL ISet&lt;int&gt;,例如:

S.ISet<int> integers = new S.HashSet<int>();

【讨论】:

  • 非常好的建议!刚才有完全相同的问题,这并没有立即发生在我身上。
  • 只有当命名空间是长位时才有效。如果类型参数本身的类型名称很长,那你就不走运了。
  • 刚刚遇到了同样的问题。我想使用泛型类中定义的常量作为构造函数的默认参数值,其中有 4 个,所以我必须输入完整的、冗长的类名,包括泛型参数和常量名。如果语言允许在泛型类inside 中使用语句,例如using C = Long.Name&lt;TKey,TValue&gt;,则可以解决此问题。在类之外,泛型参数是未知的,所以没有用。
【解决方案3】:

为泛型类型设置别名的唯一方法是按如下方式对其进行专门化。

using IntSet = System.Collections.Generic.ISet<int>;

您不能像在示例中那样为开放的泛型类型设置别名:

using MySet = System.Collections.Generic.ISet<>;

【讨论】:

  • 谢谢史蒂夫,我以后可以用这个了!
  • 为什么你的第一个例子不能在 VS2017 上编译?
【解决方案4】:

您的别名与类名本身相同,因此您仍然有歧义,就好像每个命名空间都有一个using。给类的别名一个不同的名称,即:

using FirstNamespace;
using OtherObject = SecondNamespace.MyObject;

public class Foo
{
    public void Bar()
    {
        MyObject first = new MyObject;//will be the MyObject from the first namespace
        OtherObject second = new OtherObject;
    }
}

【讨论】:

    【解决方案5】:

    在某些情况下,您可以使用继承:

    public class MyList<T1, T2> : List<Tuple<IEnumerable<HashSet<T1>>, IComparable<T2>>> { }
    
    public void Meth()
    {
        var x = new MyList<int, bool>();
    }
    

    【讨论】:

      【解决方案6】:

      你可以给一个类起别名:

      using Test = NameSpace.MyClass;
      

      仅当类不是泛型时。

      【讨论】:

      • 可以给一个泛型类起别名,你只需要在别名中指定一个具体的类型,而不是让它泛型。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-17
      相关资源
      最近更新 更多