如何不允许公开从特定类派生的类
本文关键字:派生 不允许 | 更新日期: 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();
}
}
很抱歉造成混乱。