繁体   English   中英

具有可选通用参数的通用和可覆盖 controller 方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM