【问题标题】:Why are interfaces not able to be marked as sealed?为什么接口不能标记为密封?
【发布时间】:2012-03-27 13:36:50
【问题描述】:
public sealed interface IMyInterface
{
}

给出“修改后的‘密封’对此项无效”

我可以在某些方面理解接口必须是可继承的,否则类无法实现它。

但是为什么我不能指定一个接口不应该定义一个子接口或者有办法,只是没有sealed

编辑

我应该努力解释我为什么想要这个。我经常看到开发人员应该使用组合的接口继承链。 Sealed 非常适合在类中执行此操作,我想知道是否有办法对接口强制执行相同的操作。在我看来,不必要的继承使得重构和维护变得更加困难。

编辑 2

根据 cmets 和帖子的反映,接口继承树不可能像对象继承树那样复杂。当您从另一个接口IX 派生时,您所说的只是“还必须实现IX”。防止这种情况没有任何好处。

【问题讨论】:

  • 你会用这个做什么?你的意思是你希望一个密封的接口能够被继承,但继承类不能创建新的成员函数?还是别的什么?
  • @MrLister:我能想到的唯一可能的意思是,防止 interfaces 从接口派生。
  • 因为这是我第一次看到这个问题弹出,我希望没有人需要这个功能,这会立即回答你的问题:没有人实现这个功能,因为没有人需要它: -)
  • 我支持你,Weston,因为类继承和接口实现之间有明显的区别。如果一个接口是密封的,这对我来说意味着你不能子类化一个接口,但这并不意味着在一个类中实现它有什么不同。继承和实现是两种不同的动物。

标签: c# interface sealed


【解决方案1】:

密封类或类的虚方法的目的是降低成本。为继承而设计是昂贵的,如果你没有正确地做到这一点,它是危险的。不正确地设计继承会带来安全性、正确性和健壮性后果,因此如果您打算为继承进行设计,最好密封您的类,从而避免与设计继承相关的成本。

类需要为继承而设计,因为它们具有实现细节。接口没有实现细节。 接口可继承没有任何成本。因此没有动力添加允许密封接口的功能。

【讨论】:

  • 通过限制接口继承链来重构和维护是否没有成本效益?
  • @weston:我不知道。如果你这样做,说出来!
  • @ShuggyCoUk:如果接口被定义为internal,有没有任何类型安全的方式将实例传递给外部代码并让它们传回?考虑场景,类UsCheckingAccount,派生自UsBankAccount,和FrenchCheckingAccount,派生自FrenchBankAccount,在程序集中。我想定义一个ICheckingAccount,它可以是它们中的任何一个,但有接受ICheckingAccount 的代码知道它实际上是其中之一,而不是其他一些任意类。 (是的,我知道,类继承并不是真正的安全)。
  • @GlennSlayden “标记”类听起来像是属性的工作,而不是接口
  • 问题是关于 c# 而不是 java 或 kotlin。然而,c# 很快就会得到带有实现的接口,所以答案需要更新。
【解决方案2】:

这只会令人困惑。使用标准语法,这意味着您无法实现该接口。此外,接口不包含任何功能或字段,因此密封它没有实际用途。接口或多或少是一种契约。

从“接口继承”中密封一个接口不会做任何事情,因为人们可以只实现你的接口和另一个继承你的接口的接口。

【讨论】:

    【解决方案3】:

    sealed 在接口上下文中意味着没有类可以实现该接口。那是没有用的,因此是不允许的。

    【讨论】:

    • 可以从接口派生的接口呢?从这个角度来看,我可以看到sealed 的意义所在。然而,除此之外,可能还有其他原因使得无法从这样的限制中获得任何东西是没有意义的。
    【解决方案4】:

    sealed 关键字根本不是为接口设计的(也没有任何意义)。查看msdn文档http://msdn.microsoft.com/en-us/library/88c54tsw(v=vs.71).aspx

    【讨论】:

      【解决方案5】:

      Sealed 是类的关键字。接口的目标是让类实现它们定义的任何契约。实现接口的类可以封装,但是封装接口用处不大。

      【讨论】:

        【解决方案6】:

        接口是您的应用程序合同...当您不需要您的合同时,为什么要定义它?

        【讨论】:

          【解决方案7】:

          密封类的主要目的之一是要求该类的任何存储位置保存该精确类型的实例,而不是派生类型。尽管大多数代码不介意派生类型对象替换基类型对象时,但在许多情况下这种替换可能会出现问题。例如,一些类包含一个函数来执行与另一个相同类型的对象的相对比较,期望比较结果将产生一个可排序的序列。如果类型BarBoz 都派生自Foo,并在比较中使用任何Bar 特定或Boz 特定字段,则可能无法合理地对包含Bar 混合的序列进行排序和Boz 实例。

          接口不存在这样的目的,因为从本质上讲,接口被设计为由多个类实现。任何类都无法实现的接口将毫无用处,而只能由一个类实现的接口将毫无意义(如果IFoo 只能是Foo,那么也可以只需使用Foo 在任何地方都会倾向于使用IFoo)。

          将接口的实现限制在定义它的模块中,和/或允许接口具有internal 成员会有一些用处。我不知道为什么不允许这样做,甚至不知道允许或禁止此类事情是否比禁止它们“更容易”或更“难”。

          【讨论】:

            【解决方案8】:

            对我来说,interface 意味着 abstract keyword;所以如果一个接口是sealed,它就是sealed abstract,这似乎是一个矛盾。

            【讨论】:

            • 仅供参考,“静态”类在逻辑上既是密封的又是抽象的;你不能继承它,也不能创建实例。
            • 谢谢,埃里克。与编译器开发人员争论总是让我感到非常渺小和绿色:-)
            猜你喜欢
            • 1970-01-01
            • 2018-09-01
            • 2021-11-05
            • 2011-05-25
            • 2016-06-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-22
            相关资源
            最近更新 更多