无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”

Posted

技术标签:

【中文标题】无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”【英文标题】:Cannot implicitly convert type 'IEnumerable<T>' to 'ActionResult<IEnumerable<T>>' 【发布时间】:2020-12-18 05:10:19 【问题描述】:

我正在尝试从数据库中获取条目列表。但是我遇到了一个错误。

无法将类型“System.Collections.Generic.IEnumerable”隐式转换为“Microsoft.AspNetCore.Mvc.ActionResult>”[ API]

请帮助我。我该如何解决这个问题?

Controller.cs

public async Task<ActionResult<IEnumerable<GrantProgram>>> GetGrants()

  //This is where the error is showing. 
  return await _grants.GetGrants(); 

业务层

IGrants.cs

Task<IEnumerable<GrantProgram>> GetGrants(); 

Grants.cs

public async Task<IEnumerable<GrantProgram>> GetGrants()

    return await _grantRepository.GetGrants(); 

数据访问层

IGrantsRepository.cs

Task<IEnumerable<GrantProgram>> GetGrants(); 

GrantsRepository.cs

public async Task<IEnumerable<GrantProgram>> GetGrants()

    return await _context.GrantProgram.ToListAsync();

【问题讨论】:

@The General 是的,我知道。我想学习三层架构。在这种情况下我该如何解决这个问题? github.com/aspnet/Mvc/issues/7981 我怀疑你想要的代码类似于return new ActionResult&lt;IEnumerable&lt;GrantProgram&gt;&gt;(await _grants.GetGrants()); @mjwills 非常感谢!我的问题被某人说它是重复的而结束了。但是提到的问题的答案并没有解决我的问题。但你的解决方案奏效了! 【参考方案1】:

我怀疑你想要的代码是这样的

return new ActionResult<IEnumerable<GrantProgram>>(await _grants.GetGrants());

为什么您现有的代码不起作用?因为(根据the docs):

C# 不支持接口上的隐式转换运算符。

它暗示:

因此,将接口转换为具体类型是 必须使用 ActionResult。

严格来说这不是真的。这是一个选项,是的(例如致电ToList),但它不是必需。另一种选择(如我所示)是自己 new 向上 ActionResult 而不是依赖隐式转换)。

其他阅读:

ActionResult<IEnumerable<T>> has to return a List<T> How is ASP.NET Core able to convert any type to ActionResult<T> return type of controller actions?

【讨论】:

使用 C# 9.0 Target-typed new expressions,您的答案现在可以简化为 return new(await _grants.GetGrants());【参考方案2】:

根据文档(Controller action return types in ASP.NET Core web API,2022 年 2 月发布),如果您的方法可以返回不同的 ActionResult,请考虑仅使用 ActionResult 作为返回类型。由于此示例只有一个返回路径,因此您可以改用更简单的代码,将特定类型定义为返回值。以下是您的代码在此更改后的样子:

Controller.cs

public async Task<IEnumerable<GrantProgram>> GetGrants()

  //This is where the error is showing. 
  return await _grants.GetGrants(); 

【讨论】:

【参考方案3】:

既然你正在使用 ActionResult 考虑使用这个

public async Task<ActionResult<IEnumerable<GrantProgram>>> GetGrants()

 
  return Ok ( await _grants.GetGrants() ); 

【讨论】:

以上是关于无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”的主要内容,如果未能解决你的问题,请参考以下文章

将数组转换为 IEnumerable<T>

无法从“System.Collections.IList”转换为“System.Collections.Generic.IEnumerable<T>”

IEnumerable<T> 使用 c# 在函数内访问 T 的属性

C#定义一个泛型集合类。要求:实现Ienumerable<T>接口,T是值类型,并T取2个类型分别测试。

返回一个通用的 IEnumerable<T>

将 IEnumerable<Ienumerable<T>> 转换为 Dictionary<key,IEnumerable<T>>