C#中如何禁止外部创建子类实例同时允许跨程序集测试?
解决方案
1. 调整核心类型定义,消除基类与子类的耦合
保留Result的internal构造函数,禁止外部程序集随意继承或实例化子类,不在基类中添加任何直接创建子类的静态方法:
public abstract class Result { internal Result() { } } internal class SuccessResult : Result { } internal class FailureResult<TError> : Result { public TError Error { get; init; } }
2. 保留原有工厂权限控制逻辑
工厂接口保持不变,你自己的内部代码实现工厂逻辑,根据业务场景给用户返回对应权限的工厂实例,生产环境下用户只能通过你提供的工厂创建Result实例:
public interface IPartialResultFactory { Result Success(); } public interface IResultFactory : IPartialResultFactory { Result Error<TError>(TError error); } // 内部实现,不对外暴露 internal class ResultFactory : IResultFactory { public Result Success() => new SuccessResult(); public Result Error<TError>(TError error) => new FailureResult<TError> { Error = error }; }
这个设计下,如果你给用户返回的是IPartialResultFactory实例,用户只能调用Success方法,完全无法创建错误类型的Result,符合你限制创建权限的需求。
3. 单独提供测试专用创建入口
在你的类库中新增独立的YourLibrary.Testing命名空间,在该命名空间下提供仅用于测试的工厂,明确标注生产环境禁用:
namespace YourLibrary.Testing { /// <summary> /// 仅用于单元/集成测试的Result创建工具,生产代码禁止使用 /// </summary> [Obsolete("此类型仅用于测试场景,生产代码使用会触发编译警告/错误", false)] public static class TestResultFactory { public static Result CreateSuccess() => new SuccessResult(); public static Result CreateFailure<TError>(TError error) => new FailureResult<TError> { Error = error }; } }
如果需要完全阻断生产环境误用,可以给方法加上[Conditional("TEST")]特性,只有测试项目定义了TEST常量时,方法才会生效,生产代码调用会直接编译报错。
方案优势
- 完全消除了
Result基类和子类的耦合,后续新增子类只需要修改对应工厂实现即可,基类不需要做任何调整 - 生产环境下公开API没有额外的创建入口,用户无法绕开你提供的工厂权限限制
- 测试代码只要引用
YourLibrary.Testing命名空间,就能自由创建需要的Result实例完成集成测试
内容的提问来源于stack exchange,提问作者Jake Conkerton-Darby
相关产品推荐
相关产品推荐

