[英]Generic and overridable controller method with optional generic parameter
我有以下通用 controller:
public abstract class ControllerBase<TEntity, TEntityDto>
{
public async Task<ActionResult<IEnumerable<TEntityDto>>> GetAll()
{
...
}
}
我需要能够根据与通用 controller (返回所有实体)相同的路由上的查询参数过滤实体。 因此,我的想法是覆盖通用 controller 并将其重写为:
public abstract class ControllerBase<TEntity, TEntityDto, TQueryParams>
{
[HttpGet]
[ProducesResponseType(200)]
public async Task<ActionResult<IEnumerable<TEntityDto>>> GetAll(TQueryParams? queryParams)
{
// Notice the service layer method is called without parameters in the generic controller
var instances = await _service.GetAll();
return Ok(instances);
}
}
public class DogsController : EntityControllerBase<Dog,DogDto>
{
[HttpGet]
[ProducesResponseType(200)]
public async Task<ActionResult<IEnumerable<DogDto>>> GetAll(DogQueryParams queryParams)
{
var instances = await _service.ListDogs(queryParams.kennel, queryParams.birthYear);
return Ok(instances);
}
}
但是,我收到错误: Only non-nullable value type could be underlying of 'System.Nullable'
。
我是否使用了正确的方法?
实现所需行为的正确方法是什么? (当我需要根据可选查询参数过滤 output 时,能够覆盖基本 controller 方法GetAll
)。
编译器错误告诉您“只能标记可空,即尚未可空的”。
引用类型本质上是可以为空的。 实际上,只有在 C# 8.0 中,我们才能获得对不可为空引用类型的支持。 使用编译器开关,因为默认使用它会有问题。
反过来,结构本质上是不可为空的。 可空语法最初是为他们发明的。 使用 C# 8.0,它将获得它的第一个扩展,afaik。
由于您没有通过 where 子句限制TQueryParams
,因此编译器只能假设适用于结构和类的事物。 对于 generics,它始终使用“最小公分母”。
但请注意,即使 C# 8.0 支持不可为空的引用类型,据我所知,MSIL 实现是如此不同,您不能互换使用它们。 您仍然必须决定 class 或结构,以使用可为空的语法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.