Является ли каждая абстрактная функция виртуальной в C #, вообще? - PullRequest
20 голосов
/ 24 декабря 2008

Я смотрел на вопрос переполнения стека В чем разница между абстрактной функцией и виртуальной функцией? , и мне было интересно, следует ли рассматривать каждую абстрактную функцию как виртуальную функцию в C # или вообще?

Я был немного озадачен ответами "вы должны переопределить / вы можете переопределить" на этот вопрос. Не будучи программистом на C #, я склонен думать, что абстрактные функции являются концепцией только во время компиляции, и что абстрактные функции являются виртуальными функциями по определению, поскольку вы должны предоставить хотя бы одну, но можете обеспечить несколько реализаций ниже по иерархии.

Виртуальные функции также имеют измерение времени компиляции, так как вы не можете переопределить не виртуальную функцию, но они в основном представляют собой концепцию времени выполнения, поскольку это «просто» выбор правильной реализации метода на основе фактического получателя.

Ответы [ 5 ]

47 голосов
/ 24 декабря 2008

Да. Из раздела 10.6.6 спецификации C # 3.0 :

Когда объявление метода экземпляра включает в себя абстрактный модификатор, который Метод называется абстрактным метод. Хотя абстрактный метод неявно также виртуальный метод, это не может иметь модификатор virtual.

4 голосов
/ 24 декабря 2008

Это имеет , чтобы быть виртуальным (и Джон Скит уже вынул спецификацию, чтобы доказать, что это есть ), потому что, учитывая ссылку на абстрактный базовый класс, должна быть вызвана реализация конкретного производного класса. Например, учитывая классическую иерархию животных:

abstract class Animal{
    public abstract void Speak();
}

class Cat : Animal{
    public override void Speak(){Console.WriteLine("meow");}
}

class Dog : Animal{
    public override void Speak(){Console.WriteLine("bark");}
}

Функция, которая принимает объект Animal и вызывает его метод Speak, не будет знать, какую реализацию вызывать, если функция не была виртуальной.

static void TalkToAnimal(Animal a){
    Console.WriteLine("Hello, animal.");
    a.Speak();
}

Обратите внимание, что реализации интерфейса не виртуальные по умолчанию. Поскольку интерфейс работает не так, как класс, истинный полиморфизм не нужен, чтобы найти реализацию метода интерфейса.

2 голосов
/ 24 декабря 2008

Да, это так. Для доказательства:

abstract class A {
    public abstract void Foo();
}
class B : A {
    public override void Foo()
    { /* must do */ }
}
class C : B {
    public override void Foo()
    { /* can do */ }
}
1 голос
/ 24 декабря 2008

Да.

Объявление абстрактного свойства указывает, что средства доступа к свойству являются виртуальными, но не обеспечивает фактическую реализацию средств доступа. ( MSDN )

0 голосов
/ 24 декабря 2008

Я думаю, что вы смотрите на проблему с точки зрения "C ++" (кратко, избегайте необходимых ключевых слов, сохраняйте нажатия клавиш).

Философия C # заключается в том, что цель кода должна быть ясна при чтении исходного кода, и компилятор должен иметь возможность проверить это намерение в максимально возможной степени.

Итак, хотя в сгенерированном MSIL очень мало различий между абстрактным методом и виртуальным методом (или, между прочим, между абстрактным и неабстрактным классом; или между параметром out и параметром ref), дополнительные ключевые слова действительно что-то говорят программистам по обслуживанию и позволяют компилятору дважды проверять, что вы делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...