只要有这样的对象,我想返回Todo
对象,否则返回NotFound()
。我也只想使用由return
和??
组成的一行。以下在编译时产生错误。如何解决?
public async Task<ActionResult<Todo>> GetTodo(long id)
{
return await _context.Todos.FindAsync(id) ?? NotFound();
}
MarTim的尝试通过了编译器,
public async Task<IActionResult> GetTodo(long id)
{
return (IActionResult)(await _context.Todos.FindAsync(id)) ?? NotFound();
}
但会生成运行时错误:
答案 0 :(得分:8)
让我们简化一下:
public async Task<ActionResult<Todo>> GetTodo(long id)
{
Todo todo = await _context.Todos.FindAsync(id);
return todo ?? NotFound();
}
这里的问题是todo
和NotFound()
的类型非常不同。 todo
是Todo
,但是NotFound()
返回NotFoundResult
。两者本质上是不兼容的,并且编译器不知道应将它们都转换为ActionResult<Todo>
。
如果您想将该方法的返回类型保持为ActionResult<Todo>
,那么我能想到的最好的是一个辅助方法:
public static ActionResult<T> ResultOrNotFound<T>(T item) where T : class
{
return item != null ? new ActionResult<T>(item) : new ActionResult<T>(NotFound());
}
然后您可以编写:
public async Task<ActionResult<Todo>> GetTodo(long id)
{
return ResultOrNotFound(await _context.Todos.FindAsync(id));
}
或者,如果您可以选择返回IActionResult
,则可以执行以下操作:
public static IActionResult OkOrNull(object item)
{
return item != null ? Ok(item) : null;
}
然后您可以编写:
public async Task<IActionResult<Todo>> GetTodo(long id)
{
return OkOrNull(await _context.Todos.FindAsync(id)) ?? NotFound();
}
如果需要的话,可以使它看起来更好一点,并带有另一个重载:
public static async Task<IActionResult> OkOrNull<T>(Task<T> task) where T : class
{
T item = await task;
return item != null ? Ok(item) : null;
}
您可以写的意思是:
public async Task<IActionResult<Todo>> GetTodo(long id)
{
return await OkOrNull(_context.Todos.FindAsync(id)) ?? NotFound();
}
答案 1 :(得分:2)
public async Task<IActionResult> GetTodo(long id) =>
ToActionResult(await _context.Todos.FindAsync(id)) ?? NotFound();
private static IActionResult ToActionResult<T>(T x)
where T : class =>
x == null
? null
: ((IConvertToActionResult) new ActionResult<T>(x)).Convert();