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

Animal.Eat ではなく、IAnimal.Eat を古いものとしてマークしただけです。varキーワードはAnimal に解決されるため、animal.Eat を呼び出すと、Obsolete としてマークされたメソッドは呼び出されません。

修正するには、明示的にvarIAnimalに変更するか、より良い方法として、 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 animalいないため、動作のようです。あなたがした場合:AnimalEat

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

期待どおりの警告/エラーが表示されるはずです。

于 2013-03-22T00:11:38.133 に答える
4

コンパイラは、インターフェイスからの廃止されたメソッドについては警告せず、メソッド呼び出しについてのみ警告します。これには正当な理由があります。

いつでもメソッドに名前を付けることができますEat

メソッドがインターフェイスの 1 つにも存在し、廃止とマークされているかどうか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 に答える