为什么非参数构造函数仍然可以?

Jeb*_*b50 1 c# generics inheritance class

这是接口定义指定它必须使用无参数构造函数来实例化一个新的T类,很好.

public interface IDatabase<T> where T : class, new()
{...}
Run Code Online (Sandbox Code Playgroud)

但具体的课程:

public class MyDatabase<T> : IDatabase<T> where T : class, new()
{
  public MyDatabase(string conString)
  {...}
}
Run Code Online (Sandbox Code Playgroud)

问题

1 - 如果第一个冒号意味着MyDatabase要实现IDatabase接口,为什么还需要第二个冒号再次指定接口的约束?

2 - 内部构造函数public MyDatabase(string conString)是对接口的覆盖,如果是,则不需要第二个冒号,对吧?

Eri*_*ert 9

1 - 如果第一个冒号意味着MyDatabase要实现IDatabase接口,为什么还需要第二个冒号再次指定接口的约束?

T的这两个类型参数声明是两个完全不同的东西,都命名为T.第一个T有一个要求:作为接口的类型参数提供的任何类型必须满足这些条件.然后你使用了另一个名为T的东西,它应该符合这些条件.如果你没有where子句,那么我们无法保证类中的T实际上满足接口所需的条件!

是内部构造函数public MyDatabase(string conString)是对接口的覆盖,如果是,则第二个冒号不是必需的,对吧?

我不明白这个问题.我不知道"覆盖界面"是什么意思.

从评论到另一个答案:

如果接口已经指定了约束,为什么这个接口的实现类应该再次重复这些约束?当然,这里的问题没有正确答案.这应该针对微软决定以这种方式实现它的人,其他一切只是猜测.

那我是那个人,我写了一篇关于这个的文章:

https://ericlippert.com/2013/07/15/why-are-generic-constraints-not-inherited/


Dav*_*d L 7

需要额外的约束,因为您没有T在与接口匹配的具体类实现中提供任何类型信息.

编译器根本不确定T您的具体类中是否与接口的泛型约束要求相匹配.因此,编译器坚持使用"冗余"类型约束来强制它们是兼容类型.

  • 我绝对同意你的看法.为了发布功能,需要设计,实施,测试和记录此功能.在这种情况下,努力可能不值得.我个人对目前的实施情况很满意:-D (3认同)