C# 泛型 : Explicit restate of inherited constraints in overriden methods could break polymorphism?

标签 c# generics

Mark Michaelis 在他的书(C# 4.0 Essentials)中写道:

class EntityBase<T> where T : IComparable<T>
{
    public virtual void Method<T>(T t)
      where T : IComparable<T>
    {
        // ...
    }
}

class Entity<T> : EntityBase<T> where T : IComparable<T>
{
    public override void Method<T>(T t)
        // Error: Constraints may not be
        // repeated on overriding members
    where T : IComparable<T>
    {
        // ...
    }
}

However, overriding members need to conform to the “interface” defined in the base class method. Additional constraints could break polymorphism, so they are not allowed and the type parameter constraints on the override method are implied.

有人可以向我解释打破多态性是什么意思吗?在这个例子中,多态性如何打破?

最佳答案

他的示例令人困惑,部分原因是(不正确,IMO)重新使用了 T对于泛型类型中的泛型方法。两个T不一样!所以;让我们使用非泛型类型:

class EntityBase
{
    public virtual void Method<T>(T t)
      where T : IComparable<T>
    {
        // ...
    }
}

class Entity : EntityBase
{
    public override void Method<T>(T t)
        // Error: Constraints may not be
        // repeated on overriding members
    where T : IComparable<T>, ISomethingElse
    {
        // ...
    }
}

这里我加了ISomethingElse - 显然,第二种方法可以尝试使用第二种方法的特征 T - 但是,调用者可能是:

EntityBase foo = GetEntity(); // is actually an Entity (sub-type) instance
foo.Method<SomeType>();
...
EntityBase GetEntity() { return new Entity(); }

基本实现不强制执行 ISomethingElse ,所以编译器不会提示它没有实现。那么重写的方法有什么作用呢?因此它不可能存在。

但是!相反,如果您在类型级别执行此操作,它确实有效,因为对于存在的具体对象我们知道约束是强制执行的:

class EntityBase<T> where T : IComparable<T>
{
    public virtual void Method(T t)
    {
        // ...
    }
}

class Entity<T> : EntityBase<T>
   where T : IComparable<T>, ISomethingElse
{
    public override void Method(T t)
    {
        // ... can use ISomethingElse features
    }
}

还有一个简短的提醒——如果你有一个带有 <T> 的泛型类型, 不要同时使用 <T>在通用方法中;更具体的东西,比如 TValue等等……

关于C# 泛型 : Explicit restate of inherited constraints in overriden methods could break polymorphism?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6242823/

相关文章:

c# - 连续 2 个 c# 程序游戏

java - 泛型中不同赋值之间的差异

java - Collections.emptyList() 和/或 Java 泛型方法的奇怪类型推断行为?

typescript - 内部包含任何泛型的数组

java - 泛型作为方法返回类型

c# Web Api - 所有 api 响应的通用包装器类

c# - 在 json 之外的 C# 中创建动态对象

c# - 在 C# 3.0 中,是否存在仅当 foreach 没有任何迭代时才会运行的代码块的任何语法?

c# - 当触发 Masstransit 消费者时启动新的 LifetimeScope

c# - WPF 绑定(bind)警告