为何使用IEvaluationService需重复传泛型参数?能否简化?
问题背景
我创建了包含通用功能的BaseService,供所有继承BaseObject的实体使用,比如Committee实体:
public interface IBaseService<T> where T : BaseObject { } public class BaseService<T> : IBaseService<T> where T : BaseObject { }
注入代码:
services.AddScoped(typeof(IBaseService<>), typeof(BaseService<>));
使用时直接指定实体类型:
readonly IBaseService<Committee> _committeeService;
但对于Evaluation实体(同样继承BaseObject),我需要带有额外业务逻辑的专属服务,于是创建了继承基础服务的特定泛型服务:
public interface IEvaluationService<T> : IBaseService<T> where T : Evaluation { } public class EvaluationService<T> : BaseService<Evaluation>, IEvaluationService<Evaluation> { }
注入代码:
services.AddScoped(typeof(IEvaluationService<>), typeof(EvaluationService<>));
使用时必须写成:
readonly IEvaluationService<Evaluation> _evaluationService;
我的疑问是:明明IEvaluationService<T>的定义中已经限定了T为Evaluation,为什么使用时还要重复传入<Evaluation>?能不能简化成readonly IEvaluationService _evaluationService;?
解答
为什么必须传入类型参数
IEvaluationService<T>本质还是开放泛型类型,虽然通过where T : Evaluation约束了类型参数的范围,但并没有固定T的具体值。比如如果后续有SpecialEvaluation : Evaluation这样的子类,IEvaluationService<SpecialEvaluation>也是符合约束的合法类型。编译器无法自动推断你要的是哪个具体的封闭泛型类型,所以必须显式指定T的具体值。
简化方案:改用非泛型专属服务
如果你的EvaluationService只需要针对Evaluation本身,不需要支持它的子类,完全可以把接口和实现改成非泛型的,这样就能实现你想要的简化写法:
- 定义非泛型专属接口
// 继承已有的IBaseService<Evaluation>,保留通用功能 public interface IEvaluationService : IBaseService<Evaluation> { // 在这里定义Evaluation专属的业务方法 }
- 实现非泛型服务类
// 直接继承BaseService<Evaluation>,不需要泛型参数 public class EvaluationService : BaseService<Evaluation>, IEvaluationService { // 实现Evaluation专属的业务逻辑 }
- 注入服务
services.AddScoped<IEvaluationService, EvaluationService>();
- 使用时无需指定类型参数
readonly IEvaluationService _evaluationService;
额外说明
如果后续需要支持Evaluation的子类扩展,也可以同时保留泛型版本和非泛型版本:泛型版本用于子类的专属服务,非泛型版本专门针对Evaluation本身,兼顾扩展性和简洁性。
内容的提问来源于stack exchange,提问作者Dr. MAF

