隐藏(使用“new”修饰符)接口方法声明的目的是什么?

可以将接口中的方法声明标记为“ new ”,但它是否具有任何“技术”意义,或者它只是一种明确声明声明不能覆盖前一个声明的方法?

例如 :

interface II1 { new void F(); } interface II2 : II1 { new void F(); } 

是有效的(C#4.0编译器不会抱怨)但似乎与以下内容不同:

 interface II1 { void F(); } interface II2 : II1 { void F(); } 

提前感谢您提供任何信息。

编辑:你知道一个隐藏在界面中会有用的场景吗?

编辑:根据这个链接: 方法隐藏是一个好主意 (谢谢斯科特),最常见的情况似乎是协变返回类型的模拟。

第二个示例发出以下编译器警告:

‘II2.F()’隐藏了inheritance成员’II1.F()’。 如果要隐藏,请使用new关键字。

我会说使用new关键字的不同之处在于:显示意图。

两者非常不同。 通过使用’new’,您将创建一个新的inheritance链。 这意味着II2任何实现都需要实现两个版本的F() ,而最终调用的实际版本将取决于引用的类型。

考虑以下三种实现:

  class A1 : II1 { public void F() { // realizes II1.F() } } class A2 : II2 { void II1.F() { // realizes II1.F() } void II2.F() { // realizes II2.F() } } class A3 : II2 { public void F() { // realizes II1.F() } void II2.F() { // realizes II2.F() } } 

如果你有A2的引用,你将无法在没有首先转换为II1II2情况下调用任何一个版本的F()

 A2 a2 = new A2(); a2.F(); // invalid as both are explicitly implemented ((II1) a2).F(); // calls the II1 implementation ((II2) a2).F(); // calls the II2 implementation 

如果您有对A3的引用,则可以直接调用II1版本,因为它是隐式实现:

 A3 a3 = new A3(); a3.F(); // calls the II1 implementation ((II2) a3).F(); // calls the II2 implementation 

我知道一个很好的用途:你必须这样做来声明一个从另一个COM接口派生的COM接口。 在这篇杂志文章中有所涉及。

Fwiw,作者完全错误地认定了问题的根源,它与“遗产税”无关。 COM简单地利用了典型的C ++编译器实现多重inheritance的方式。 每个基类都有一个v表,正是COM需要的。 CLR没有这样做,它不支持MI,只有一个v-table。 接口方法合并到基类的v表中。

new修饰符非常简单,它只是抑制隐藏方法时创建的编译器警告。 如果在不隐藏其他方法的方法上使用,则会生成警告。

来自C#语言规范3.0

10.3.4 new修饰符允许class-member-declaration声明与inheritance成员具有相同名称或签名的成员。 发生这种情况时,称派生类成员隐藏基类成员。 隐藏inheritance的成员不被视为错误,但它确实会导致编译器发出警告。 要禁止警告,派生类成员的声明可以包含一个新修饰符,以指示派生成员是否要隐藏基本成员。 本主题将在§3.7.1.2中进一步讨论。 如果新修饰符包含在不隐藏inheritance成员的声明中,则会发出对该效果的警告。 删除新修饰符可以抑制此警告。

Fredrik回答后的一个例子。 我想有一个接口,表示通过id获取实体的方法。 然后我想要一个WCF服务和一些其他标准存储库能够用作该接口。 为了使用WCF,我需要使用属性来装饰我的界面。 从一个意图的角度来看,我不想用WCF东西装饰我的界面,因为它不会仅通过WCF使用,所以我需要使用new。 这是代码:

 public class Dog { public int Id { get; set; } } public interface IGetById { TEntity GetById(int id); } public interface IDogRepository : IGetById { } public class DogRepository : IDogRepository { public Dog GetById(int id) { throw new NotImplementedException(); } } [ServiceContract] public interface IWcfService : IGetById { [OperationContract(Name="GetDogById")] new Dog GetById(int id); } 

我几乎在每个界面都使用它。 看这里:

 interface ICreature { ///  /// Creature's age ///  ///  /// From 0 to int.Max ///  int GetAge(); } interface IHuman : ICreature { ///  /// Human's age ///  ///  /// From 0 to 999 ///  new int GetAge(); } 

拥有一个要求较低但义务较大的inheritance成员是绝对正常的。 LSP没有被违反。 但如果是的话,在哪里记录新合同?