Единственная причина, по которой я могу придумать, заключается в том, что иногда вам нужно писать защищенные методы для переопределения других защищенных методов. Язык мог бы быть спроектирован таким образом, чтобы:
protected override void Foo()
но не это
protected void Foo()
но за этим, возможно, было бы трудно понять - это отсутствие из override
делает его бесполезным, тогда как в случае
public virtual void Foo()
бесполезно присутствие из virtual
. Присутствие чего-то «неправильного», вероятно, легче понять, чем отсутствие чего-то полезного.
В этом случае виртуальность может также влиять на производительность, в то время как создание чего-то защищенного, а не частного, вероятно, не делает - так что это немного серьезнее.
Это всего лишь догадки, хотя на самом деле - если нам действительно повезет, Эрик Липперт даст более определенный ответ. Он тот, кого ты хочешь, а не я :)
Лучший ответ: воспринимать предупреждения как ошибки, и они в любом случае эквивалентны;)