8

考虑这个例子

    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

4

3 回答 3

15

您只将 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");
        }
    }
于 2013-03-22T00:10:14.050 回答
8

看起来这种行为是因为你var animalAnimal方法Eat没有过时。如果你这样做了:

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

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

于 2013-03-22T00:11:38.133 回答
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()'

于 2013-03-22T00:12:13.757 回答