标记为Obsolete的接口方法在实现时不会从编译器发出消息

考虑这个例子

public interface IAnimal { [Obsolete("Animals can't eat anymore", true)] void Eat(); } public class Animal : IAnimal { public void Eat() { Console.WriteLine("Hello"); } } 

我有一个接口IAnimal与一个废弃的方法。 Class Animal实现了该接口。

稍后,我称之为Eat方法:

 var animal = new Animal(); animal.Eat(); 

编译器编译失败(我已将Obsolete标记为给出错误而不是警告)。 程序编译并调用方法,没有错误。

据我所知,这是编译器的一个错误。 我错过了什么吗?

注意:我使用的是VS2010

您只将IAnimal.Eat标记为过时,而不是Animal.Eat。 var关键字解析为Animal,因此当您调用animal.Eat时,您不会调用任何标记为Obsolete的方法。

要修复,要么显式将var更改为IAnimal ,要么更好,将Animal.Eat标记为已过时:

  public interface IAnimal { [Obsolete("Animals can't eat anymore", true)] void Eat(); } public class Animal : IAnimal { [Obsolete("Animals can't eat anymore", true)] public void Eat() { Console.WriteLine("Hello"); } } 

看起来这种行为是因为你的var animal是一种Animal ,其中Eat方法不会过时。 如果你这样做:

 IAnimal animal = new Animal(); animal.Eat(); 

你应该看到你期望的警告/错误。

编译器不会警告接口中的过时方法,仅针对方法调用。 这有很好的理由:

您可以随时命名您的方法Eat

您始终可以实现Eat on Animal方法,无论它是否也出现在其中一个接口中并标记为过时。 例如,如果允许:

 public class Animal { public void Eat() { /* ... */ } } 

为什么不允许这样做:

 public class Animal : IAnimal { public void Eat() { /* ... */ } } 

必须实现所有接口方法

您需要实现接口中存在的所有方法。 你不能跳过任何一个,即使它们已经过时了。

例如,如果您没有添加Eat ,那么您将不会实现该界面的所有成员,并且您会收到其他错误:

 public class Animal : IAnimal { // No Eat() } 

‘Animal’没有实现接口成员’IAnimal.Eat()’