ASP.NET Core ActionResult返回值隐式转换报错咨询
错误成因
这个报错是C#隐式转换规则和ASP.NET Core ActionResult<T>类型的转换逻辑共同导致的,核心原因如下:
C#不支持链式隐式转换:一次类型转换过程中,最多只能执行一次用户自定义的隐式转换,不会自动串联多步转换。
你的代码里_mapper.Map<IEnumerable<CommandReadDto>>()实际返回的是具体集合类型(比如List<CommandReadDto>、CommandReadDto[]这类实现了IEnumerable<CommandReadDto>接口的类型),要转成方法声明的返回类型ActionResult<IEnumerable<CommandReadDto>>需要两步:- 把具体集合类型做隐式引用转换,转为接口类型
IEnumerable<CommandReadDto>(也就是ActionResult<T>的泛型参数T) - 调用
ActionResult<T>定义的自定义隐式转换运算符,把T类型转为ActionResult<T>
两步隐式转换串联,编译器无法自动完成,所以直接抛出转换错误。
- 把具体集合类型做隐式引用转换,转为接口类型
Ok()方法绕开了多步转换的限制:用Ok()包装返回值时,Ok()方法返回的是OkObjectResult类型,这个类型直接继承自ActionResult抽象类。而ActionResult<T>本身定义了从ActionResult类型到自身的自定义隐式转换,整个过程只需要一次用户自定义转换,编译器可以正常识别执行,所以代码能正常运行。
补充解决方式
如果不想用Ok()包装返回值,只需要显式把映射结果转为IEnumerable<CommandReadDto>类型再返回即可,示例代码:
return (IEnumerable<CommandReadDto>)_mapper.Map<IEnumerable<CommandReadDto>>(commandItems);
这种写法下返回值的静态类型就是泛型参数T,只需要一步隐式转换就能匹配方法返回类型,不会触发编译错误。
内容的提问来源于stack exchange,提问作者Hossein Dara
相关产品推荐
相关产品推荐

