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

时间:2013-03-22 00:07:20

标签: c# compiler-construction

考虑这个例子

    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

3 个答案:

答案 0 :(得分:12)

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

要修复,要么明确地将 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");
        }
    }

答案 1 :(得分:8)

行为似乎是因为您的var animalAnimal Eat方法,其中IAnimal animal = new Animal(); animal.Eat(); 方法尚未过时。如果你这样做了:

{{1}}

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

答案 2 :(得分:4)

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

您可以随时命名方法Eat

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

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

为什么不允许这样做:

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

必须实现所有接口方法

您需要实现界面中存在的所有方法。你不能跳过它们中的任何一个,即使它们已经过时也是如此。

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

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

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