为什么我需要在泛型子类中重新声明类型约束

Pau*_*aul 15 c# generics inheritance type-constraints

最近我尝试通过实现通用接口来创建通用子类.

public interface IModule<T> where T : DataBean { ..... }
public class Module<T> : IModule<T> where T : DataBean { .... } 
Run Code Online (Sandbox Code Playgroud)

似乎我不能依赖于基本接口中定义的任何T限制,我需要自己重新声明它们.

MSDN刚刚提供:

使用子类泛型类型参数时,必须重复子类级别的基类级别规定的任何约束.例如,派生约束

为什么不能从基类/接口推断出约束?

Phi*_*eck 6

我无法提出任何理由说c#理论上无法复制约束.但是,使我们明确地复制(或增加)它们的记录行为似乎是可用性的最简单方式.

public class A{}
public class B : A {}

public class X<T> where T: A {}
public class Y<T> : X<T> where T: B { }
Run Code Online (Sandbox Code Playgroud)

在上面的,请注意,我没有给explicty拷贝过来的约束 Y<T>,因为B永远A.

现在让我们看看如果"编译器自动复制约束"会发生什么.假设我Y<T>没有约束地定义,编译器会自动放置它们.我用Y<T>了很多代码.然后我更改声明的约束X<T>以包含一些新接口.

更改声明的编译器错误X<T>位于我使用 的站点Y<T>!

通过c#编译器当前工作的方式,编译器错误正在使用X<T>,正如我所期望的那样,如果我以突破方式更改它.

因此,虽然在某些情况下会很方便,但在其他情况下也会有些混乱.虽然两者都是有效的方法,但我会假设(注意我无法读懂c#设计团队的想法)它是一个判断调用,而不是纯粹的技术调用.

我说"不是纯粹技术性的",但我当然可以想象一些界面场景,它可以更简单地验证是否满足所有约束,而不是产生满足所有必需的继承约束的最简单约束.


Han*_*ant 5

标准C#团队智慧.声明应该是自我记录的.最重要的是,一种类型声明的更改不应该在不生成诊断的情况下改变不相关的其他类型的行为.设计的-100点原则是另一个考虑因素.