C#接口实现解析疑问:IB接口标记new的Method为何复用BaseA中的实现?
嗨,我来帮你把这个问题掰扯明白!你之所以有疑惑,核心是没搞清楚接口里的new修饰符到底起什么作用,以及C#里接口实现的匹配规则。
首先,咱们先拆解IB里的[Custom] new void Method();:这里的new并不是要求实现类必须重新写一个新的方法,它的作用是明确告诉编译器:IB里的这个Method是一个独立于IA.Method的全新接口成员,不是对IA.Method的重写——说白了就是用来解决接口继承时的名称冲突,避免编译器报“隐藏继承成员”的警告,但它并没有改变方法的签名(依然是void Method()),也没有强制要求实现类必须提供新的实现。
接下来看Class C的情况:BaseA已经实现了IA的Method(),而C继承了BaseA同时实现IB。这时候C本身没有显式写Method(),为什么编译器不报错?因为C#的接口实现规则是这样的:
- 当类实现某个接口时,只要类中存在一个可访问的、签名完全匹配的非静态方法(不管这个方法是自己定义的,还是从基类继承来的),就可以作为该接口方法的实现。
- IB里的
new Method()虽然标记了new,但它的签名和IA的Method完全一致,BaseA里的public void Method()刚好符合这个签名要求,而且是public可访问的,所以C继承BaseA的这个方法后,就自动满足了IB接口的实现要求,不需要额外写新的方法。
你之前的预期误区是以为new会强制子类重新实现,但其实不是——接口里的new只是修改了接口成员的名称解析逻辑(比如当你通过IB类型的引用调用Method时,会优先绑定到IB的成员,但因为实现是同一个,所以效果和IA调用一样),但并没有改变“签名匹配即可复用现有实现”的规则。
那C#规范里哪里明确了这个逻辑呢?在接口成员的继承和实现匹配章节里有说明:当接口使用new修饰符声明一个与基接口同名的成员时,该成员会隐藏基接口中的对应成员,但在实现该接口时,只要类中的方法与接口成员的签名(返回类型、参数列表)兼容,就可以作为实现,无论这个方法是继承自基类还是类自身定义的。
举个反例就好理解了:如果IB的Method改成void Method(int num);,那BaseA的方法签名就不匹配了,这时候Class C就必须自己实现这个带参数的Method,否则编译器就会报错。
备注:内容来源于stack exchange,提问作者Naser Asadi

