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

发布于 2024-10-07 20:22:39 字数 716 浏览 9 评论 0原文

给定这个接口

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;
    }
}

Given this interface

public interface IMyInterface
{
    string Method1();
}

Why is this valid

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

But this isnt

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

And yet it is a valid scenario for an abstract class

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

童话 2024-10-14 20:22:40

因为默认情况下每个方法都是密封的,除非它是虚拟的,或者除非您不对已经是虚拟的并且您要覆盖的东西说密封

Because every method is by default sealed, unless it's virtual, or unless you don't say sealed on something that's already virtual and that you're overriding.

祁梦 2024-10-14 20:22:40

默认情况下,类中的每个方法都是密封的(在 VB.NET 中为 NotOverridable),除非您专门将其声明为 virtual(在 VB.NET 中为Overridable)。网)。

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

Every method in a class is sealed (NotOverridable in VB.NET) by default, unless you specifically declare it as virtual (Overridable in VB.NET).

As you've said, this is not the case with classes. You have to specifically indicate that you want to forbid inheriting from a class using sealed (or NotInheritable in VB.NET).

温暖的光 2024-10-14 20:22:40

只是提醒一下,C# 中的接口方法不能被密封

考虑以下代码:

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 被派生类覆盖。被密封的方法不是接口方法,而是Base的方法。

也就是说,隐式实现

class ImplicitImpl : IFoo
{
    public void Bar() { Blah; }
}

应被视为以下语义上等效的显式实现:

class ImplicitImplEquiv : IFoo
{
    public void Bar() { Blah; }
    void IFoo.Bar() { this.Bar(); }
}

如果 ImplicitImplEquiv 的派生类只是用另一个 public 隐藏 public void Bar void Bar,调用 ((IFoo)ref).Bar() 仍会调用 ImplicitImplEquiv.Bar。但如果派生类也重新继承IFoo并提供新的实现,则接口vtable将与ImplicitImplEquiv不同。

Just a reminder that interface methods in C# cannot be sealed.

Consider the following code:

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"); }
}

And then, if we have var d = new Derived(), we'll have:

  • d.Bar() writes Derived.Bar
  • ((Base)d).Bar() writes Base.Bar
  • ((IFoo)d).Bar() writes Derived.Bar
  • ((IFoo)(Base)d).Bar() writes Derived.Bar

The interface method Bar is overridden by the derived class. The method that is sealed is not the interface method, but a method of Base.

That is to say, an implicit implementation

class ImplicitImpl : IFoo
{
    public void Bar() { Blah; }
}

should be considered as the following semantically equivalent explicit implementation:

class ImplicitImplEquiv : IFoo
{
    public void Bar() { Blah; }
    void IFoo.Bar() { this.Bar(); }
}

If a derived class of ImplicitImplEquiv simply hides public void Bar with another public void Bar, calling ((IFoo)ref).Bar() will still invoke the ImplicitImplEquiv.Bar. But if the derived class also reinherits IFoo and provides a new implementation, the interface vtable will be different than that of ImplicitImplEquiv.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文