Просто напоминание о том, что методы интерфейса в C # не могут быть sealed
.
Рассмотрим следующий код:
interface IFoo
{
void Bar();
}
class Base : IFoo
{
public void Bar() { Console.WriteLine("Base.Bar"); }
}
class Derived : Base, IFoo
{
public new void Bar() { Console.WriteLine("Derived.Bar"); }
}
И затем, если у нас есть var d = new Derived()
, у нас будет:
d.Bar()
пишет Derived.Bar
((Base)d).Bar()
пишет Base.Bar
((IFoo)d).Bar()
пишет Derived.Bar
((IFoo)(Base)d).Bar()
пишет Derived.Bar
Метод интерфейса Bar
переопределяется производным классом. Метод sealed
- это не интерфейсный метод , а метод Base
.
То есть неявная реализация
class ImplicitImpl : IFoo
{
public void Bar() { Blah; }
}
следует рассматривать как следующую семантически эквивалентную явную реализацию:
class ImplicitImplEquiv : IFoo
{
public void Bar() { Blah; }
void IFoo.Bar() { this.Bar(); }
}
Если производный класс ImplicitImplEquiv
просто скрывает public void Bar
с другим public void Bar
, вызов ((IFoo)ref).Bar()
все равно вызовет ImplicitImplEquiv.Bar
. Но если производный класс также наследует IFoo
и предоставляет новую реализацию, интерфейс vtable будет отличаться от интерфейса ImplicitImplEquiv
.
Для дальнейшего обсуждения этой темы вы можете прочитать мое сообщение в блоге https://geelaw.blog/entries/csharp-interface-sealed/ (статья только на китайском языке в настоящее время, но содержит хорошие фрагменты кода, которые помогут вам понять проблему).