有没有办法创建一个无法在其程序集之外实现的公共 .NET 接口

本文关键字:实现 程序集 接口 NET 创建 一个 有没有 | 更新日期: 2023-09-27 18:30:00

为了在 .NET 中保持二进制向后兼容性,通常不能向公共类和接口添加新的抽象方法。如果这样做,则针对扩展/实现类/接口的旧版本的程序集生成的代码将在运行时失败,因为它无法完全扩展/实现新版本。但是,对于类,有一个方便的解决方法:

public abstract class Foo {
    internal Foo() { }
}

因为 Foo 的构造函数是内部的,所以我的程序外部没有人可以扩展 Foo。因此,我可以向Foo添加新的抽象方法,而不必担心向后兼容性,因为我知道另一个程序集中的任何类都无法扩展Foo。

我的问题是,接口有类似的技巧吗?我是否可以创建一个公共接口,并以某种方式保证程序集外部的任何人都无法创建它的实现?

有没有办法创建一个无法在其程序集之外实现的公共 .NET 接口

不,你不能那样做。但是,考虑到接口的要点是通过定义协定来定义实现的行为,这是有道理的。

但是,您可以做的是创建一个继承自public interfaceinternal interface

public interface IPublicInterface {
    /* set-in-stone method definitions here */
}
internal interface IChildInterface : IPublicInterface  {
    /* add away! */
}

这应该可以防止与其他程序集出现任何向后兼容性问题,同时仍允许您隐藏其他方法。

当然,缺点是您必须记住在需要时投射为IChildInterface,而不是简单地将其用作IPublicInterface

不过,老实说,如果您真的想定义一些仅程序集功能,同时仍然要求最终用户为某些方法定义自己的实现,那么您最好的选择可能是抽象类。

不,你不能。

但是由于在 IL 中接口本质上只是一个纯粹的抽象类(即根本没有任何实现的类(,您可以使用已经描述的技术,它实际上是相同的。

如前所述,请记住,此方法确实将类型限制为仅继承虚假的"抽象类"接口。它可以实现其他接口,但不能继承任何其他类型。这可能是也可能不是问题,具体取决于方案。

如果它使你对设计感觉更好,请按照接口的 .NET 约定命名纯抽象类。 例如 IFoo而不是Foo.

当然,这确实暗示了一个问题:你为什么要这样做?如果你根本没有实现,允许其他代码实现你的接口会有什么危害?

但从实际的角度来看,可以按照您想要的方式执行您的规则。