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

C# 为什么我需要在泛型子类中重新声明类型约束,c#,generics,inheritance,type-constraints,C#,Generics,Inheritance,Type Constraints,最近,我试图通过实现一个泛型接口来创建一个泛型子类 public interface IModule<T> where T : DataBean { ..... } public class Module<T> : IModule<T> where T : DataBean { .... } 公共接口IModule,其中T:DataBean{….} 公共类模块:IModule,其中T:DataBean{….} 似乎我不能依赖于基本接口中定义的任何t限制,

最近,我试图通过实现一个泛型接口来创建一个泛型子类

public interface IModule<T> where T : DataBean { ..... }
public class Module<T> : IModule<T> where T : DataBean { .... } 
公共接口IModule,其中T:DataBean{….}
公共类模块:IModule,其中T:DataBean{….}
似乎我不能依赖于基本接口中定义的任何t限制, 我需要自己重新申报

刚刚提供:

使用子类泛型类型时 参数,则必须重复任何 基地规定的限制条件 子类级别的类级别。对于 例如,派生约束


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

我想不出c#理论上不能复制约束的任何理由。但是,让我们复制(或扩充)它们的记录行为似乎是可用性的最简单方式

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

public class X<T> where T: A {}
public class Y<T> : X<T> where T: B { }
公共类A{}
公共B类:A{}
公共类X,其中T:A{}
公共类Y:X,其中T:B{}
在上面,请注意,我不必解释复制
Y
上的约束,因为a
B
总是a
a

现在让我们看看如果“编译器自动复制约束”会发生什么。假设我在没有约束的情况下定义
Y
,编译器会自动放置它们。我在很多代码中使用
Y
。然后我更改
X
声明上的约束,以包含一些新接口

更改
X
声明的编译器错误出现在我使用
Y
的站点

按照c#编译器目前的工作方式,编译器错误出现在
X
的用法上,如果我以一种破坏性的方式对其进行更改,我会预料到这一点

因此,虽然在某些情况下这会很方便,但在其他情况下也会有些混乱。虽然这两种方法都是有效的,但我认为(注意,我无法理解c#设计团队的想法)这是一种判断,而不是纯粹的技术


我说“不完全是技术性的”,但我可以肯定地想象一些接口场景,在这些场景中,验证所有约束都得到满足比生成满足所有必需继承约束的最简单约束要简单一些

标准C#团队智慧。声明应该是自文档化的。最重要的是,一个类型声明中的更改不应在不生成诊断的情况下改变不相关的其他类型的行为。在设计中使用的-100点原则是另一种解释。

接口上的结构过于复杂,无法告诉编译器模块类应该具有哪些约束。例如,模块类可以对DataBean的超类(继承类)具有约束


我不知道C#设计师的智慧。因为约束可能不同,我认为决定让开发人员显式声明约束,而不是让编译器进行假设。

约束不需要复制,您也可以选择使用可转换为父约束类型的东西,使子类更加专业化。C#4.0规范几乎说了同样的话(§13.4.3),但没有提供原因。如果子类中的泛型参数与基类中的泛型参数有矛盾的约束,会发生编译错误吗