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

本文关键字:编译器 消息 实现 Obsolete 记为 接口 方法 | 更新日期: 2023-09-27 18:05:07

考虑以下示例

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

我有一个带有过时方法的IAnimal接口。类Animal实现了这个接口。

之后,我这样调用Eat方法:

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

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

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

注意:我使用VS2010

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

你只标记了IAnimal。吃是过时的,而不是动物。var关键字解析为Animal,当调用Animal时也是如此。注意,你没有调用任何标记为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 animalAnimal,其中Eat方法并未过时。如果你做了:

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

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

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

你可以将你的方法命名为Eat

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

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

为什么不允许:

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

所有接口方法必须实现

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

例如,如果您没有添加Eat,您就不会实现接口的所有成员,并且会得到其他错误:
public class Animal : IAnimal
{
    // No Eat()
}

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