c# - 覆盖泛型方法的约束

标签 c# generics

我试图了解约束(在类或泛型方法上)如何影响方法本身。以这段代码为例:

class Base<T> where T:class, IComparable<T>
{
    public virtual void Method(T obj) { }
}

class Derived<T> : Base<T> where T:class, IComparable<T>, IEnumerable<T>
{
    public override void Method(T obj) { }
}

此代码编译良好,编译器/运行时能够解析对非泛型方法“Method”的多态调用,该方法采用泛型类型的参数。在基类和派生类中,对类型参数的约束是不同的。

我还指定了一个类约束来排除值类型,这可能会导致问题,因为为每个值类型实例化生成不同的类,而对于引用类型只实例化一个这样的类。

另一方面,以下代码无法编译。

class Base
{
    public virtual void Method<T>() where T : class, IComparable<T> { }
}

class Derived : Base
{
    public override void Method<T>() where T : class, IComparable<T>, IEnumerable<T> { }
}

C# 的语言规范指出,对泛型方法的约束会像覆盖方法一样被继承,并且指定任何此类约束都是非法的。我在 Google 上进行了一些搜索,发现这是不允许的,因为与支持多态调用相关的复杂性(关于维护方法表等)。但我仍然不明白为什么它在上面的案例 1 中起作用,除了它是通用的类之外​​,它与此类似。当情况 2 被标记为编译器错误时,编译器/运行时如何能够在情况 1 中执行此操作?

最佳答案

在情况 1 中,当 T 由类确定时,该方法可用于类型 T 的任何对象。对于任何特定的类,只有一种类型 T,因此覆盖很简单。事实上,与生成 Derived 相比,您可以使用更广泛的类型 T 来生成 Base 是没有问题的。

在情况 2 中,可以为任意数量的类型调用方法。但是,Derived 类中允许的类型只是 Base 类中允许的类型的一个子集,这意味着您有一个“部分覆盖”,这让事情变得一团糟。

关于c# - 覆盖泛型方法的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38565483/

相关文章:

c# - 无法连接到 LINQ to SQL 网页上的 SQL 服务器

java - 使用 Java 泛型和工厂模式返回类型的最佳实践是什么

c# - 具有泛型类声明的命名空间约束

ios - swift/iOS : Generics Error: protocol requires nested type 'V' ; do you want to add it?

c# - 十次 Thread.Sleep(100) 还是一次 Thread.Sleep(1000)?

c# - 拆分包含空格的字符串,除非它们包含在 "quotes"中?

c# - Windows 手机 7 - 仅限 C#?

c# - 事件是 OO 等同于 GOTO 吗?

swift - 协议(protocol)不符合自身?

c# - 可以创建 key 未知的通用搜索方法