【问题标题】:How to specify types not allowed in a .NET Generics constraint?如何指定.NET 泛型约束中不允许的类型?
【发布时间】:2011-08-17 16:36:55
【问题描述】:

是否可以对不允许某些类型的泛型类指定约束?我不知道这是否可能,如果可能,我不确定语法是什么。比如:

public class Blah<T> where : !string {
}

我似乎找不到任何允许这种约束的符号。

【问题讨论】:

  • 不认为这是可能的 - 但你为什么需要这样的东西?
  • 当有人试图传入不受支持的类型时,期望的行为是什么?
  • 我实际上是在尝试排除字符串类型,但事实证明,使用 where T : struct 适用于我正在尝试做的事情,因为我的类无论如何都不适用于复杂类型。跨度>
  • 出于兴趣,我试图找出为什么需要这种行为的原因。

标签: c# .net generics constraints


【解决方案1】:

您可以获得的最接近的是运行时约束。

编辑:最初我将运行时检查放在构造函数调用中。这实际上并不是最优的,因为它会在每次实例化时产生开销;我相信将检查放在 static 构造函数中会更明智,该构造函数将被用作 T 参数的每个类型调用一次 Blah&lt;T&gt; 类型:

public class Blah<T> {
    static Blah() {
        // This code will only run ONCE per T, rather than every time
        // you call new Blah<T>() even for valid non-string type Ts
        if (typeof(T) == typeof(string)) {
            throw new NotSupportedException("The 'string' type argument is not supported.");
        }
    }
}

显然不理想,但如果你把这个约束放在适当的位置并且证明string不是一个受支持的类型参数(例如,通过XML cmets),你应该得到某个地方接近编译时约束的有效性。

【讨论】:

  • 通常我会将 C# 中无法表达的约束放入类构造函数中。
  • 包含可以解析为字符串的类型: if (typeof(string).IsAssignableFrom(typeof(T))) throw new NotSupportedException
【解决方案2】:

不,您不能直接指定“否定”类型约束。

【讨论】:

  • 是否有间接方法,除了断言 typeof(T) 不是某物之类的方法吗?
  • @SirPentor 不是类型约束的一部分,尽管您可以在代码中执行类似的操作。
【解决方案3】:

约束只能是正约束,如documentation 中所述。

您唯一能做的就是指定哪些类型可以放入泛型类型中,但您不能指定哪些类型不能放入其中。 p>

【讨论】:

    【解决方案4】:

    这里是允许的约束 (more detail)

    • 其中 T:结构
    • 其中 T:类
    • 其中 T : new()
    • 其中 T : [基类名称]
    • 其中 T:[接口名称]
    • 其中 T : U(为 T 提供的类型参数必须是或派生自为 U 提供的参数)

    【讨论】:

      猜你喜欢
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 2023-03-17
      相关资源
      最近更新 更多