2011-01-08 79 views
15

最近我尝试通过实现通用接口来创建泛型子类。为什么我需要在通用子类中重新声明类型约束

public interface IModule<T> where T : DataBean { ..... } 
public class Module<T> : IModule<T> where T : DataBean { .... } 

看来我不能依赖于任何T的限制,是在基本接口定义, ,我需要重新申报他们自己。

MSDN只是提供:

当使用子类泛型类型 参数,则必须重复任何 限制在规定的子类级别基本 一流水平。对于 示例,推导约束

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

+1

约束不需要复制,也可以选择使用可转换为父类的约束类型的东西,使得子类更加专业化。 – 2011-01-08 17:33:31

回答

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 { } 

在上面,注意,我没得explicty拷贝过来的约束上Y<T>,因为B总是A

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

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

随着c#编译器当前的工作方式,编译器错误的用处是X<T>,正如我期望的那样,如果我以突破的方式进行更改。

所以虽然在某些情况下会很方便,但在其他情况下也会有些混乱。虽然这两种方法都是有效的方法,但我会假设(注意,我无法读懂c#设计团队的想法),认为这是一种判断,而不是纯技术。我说“不是纯粹的技术”,但我当然可以想象一些界面场景,它可以更简单地验证所有约束条件都满足,而不是产生满足所有必需的继承约束条件的最简单约束。

5

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

1

接口上的constranints太大而无法告诉编译器Module类应具有哪些约束。例如,Module类可能对DataBean的超类(继承类)有约束。

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

相关问题