为什么我可以密封一个实现接口但不能封闭成员的类?

时间:2010-12-15 07:07:20

标签: .net inheritance interface virtual sealed

鉴于此界面

public interface IMyInterface
{
    string Method1();
}

为什么这是有效的

public sealed class InheretedFromInterfaceSealed: IMyInterface
{
    public string Method1()
    {
        return null;
    }
}

但这不是

public class InheretedFromInterfaceWithSomeSealed: IMyInterface
{
    public sealed string Method1()
    {
        return null;
    }
}

然而,它是抽象类的有效方案

public abstract class AbstractClass
{
    public abstract string Method1();
}
public class InheretedFromAbstractWithSomeSealed: AbstractClass
{
    public sealed override string Method1()
    {
        return null;
    }
}

3 个答案:

答案 0 :(得分:6)

因为默认情况下每个方法都是密封的,除非它是虚拟的,或者除非你没有对已经虚拟的东西说sealed并且你正在覆盖。

答案 1 :(得分:1)

默认情况下,类中的每个方法都是密封的(NotOverridable在VB.NET中),除非您在VB.NET中明确声明它为virtualOverridable)。

正如你所说,这是类的情况。您必须明确指出要禁止使用sealed(或VB.NET中的NotInheritable)从类继承。

答案 2 :(得分:0)

提醒一下,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

派生类重写接口方法Barsealed方法 接口方法,但方法为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/(该文章目前仅提供中文,但包含可帮助您了解问题的优秀代码段。)