如何不允许公开从特定类派生的类

本文关键字:派生 不允许 | 更新日期: 2023-09-27 18:21:55

假设一个组件(比如CompA(在SDK中公开一个公共的C# .NET类(比如Base(:

namespace CompA { public abstract class Base {} } 

另一个组件(例如 ExtB(通过从以下基类派生来扩展 CompA:

namespace ExtB { class Derived : CompA.Base {} }

您有什么意见,请问不允许将类 ExtB.Derived 声明为公共的最佳方法是什么?CompA.Base 用于扩展 CompA,但不用于公开新的公共 API。

namespace ExtB { public class Derived : CompA.Base {} } // DISALLOW

我能想到的是期望公开公共 API 的程序集使用 .NET 自定义属性进行标记,并使用另一个 .NET 自定义属性标记基类。然后,加载这些程序集的产品将不允许加载公开/发布从标有自定义属性的类型派生的此类类型的程序集。

CompA的AssemblyInfo.cs:

[assembly:SdkApiAssemblyAttribute()]

ExtB的AssemblyInfo.cs:

[assembly:SdkApiAssemblyAttribute()]

底座.cs:

namespace CompA
{
    [Publishable(false)]
    public abstract class Base {}
} 

谢谢!

如何不允许公开从特定类派生的类

乍一看,你做错了什么。在确认您的意图只是为了防止意外暴露类型后,听起来很合理。编写单元测试可能很简单,但如果派生类不是代码库的一部分,则可以执行以下操作。

没有编译时方法来防止这种情况(AFAIK(。只需检查基类构造函数中的类型并引发异常。

public abstract class Base
{
    protected Base()
    {
        if (this.GetType().IsPublic)
            throw new InvalidOperationException("Type is not meant to be exposed public");
    }
}
public class Der : Base
{
    public Der()
    {
    }
}

这将阻止客户端创建新的Der实例(如果它被声明为 public (。

注意:有些场景构造函数不会运行,那你就不走运了。幸运的是,它们是极端情况,无需担心太多。例如:FormatterServices.GetUninitializedObject 不会运行构造函数。

@SriramSakthivel,你是对的:我做错了什么! :)

虽然不是故意的,但我并没有说CompA.Base实际上不是一个类,而是一个接口

public interface Base
{
    string ShouldNotBePublic();
}

基类应公开具有受保护访问修饰符的方法:

public abstract class Base
{
    protected string ShouldNotBePublic();
}

这样,派生类就不会酸性地公开受保护的信息。然后,组件 CompA 能够通过实现模板方法模式来访问此方法:

namespace CompA
{
    public abstract class Base : IBaseInternal
    {
        protected string ShouldNotBePublic();
        string IBaseInternal.ShouldNotBePublic()
        {
            return ShouldNotBePublic();
        }
    }
    internal interface IBaseInternal
    {
        string ShouldNotBePublic();
    }
}

很抱歉造成混乱。