如何使用 ??有回报吗?

时间:2019-10-16 11:34:37

标签: c#

只要有这样的对象,我想返回Todo对象,否则返回NotFound()。我也只想使用由return??组成的一行。以下在编译时产生错误。如何解决?

public async Task<ActionResult<Todo>> GetTodo(long id)
{
    return await _context.Todos.FindAsync(id) ?? NotFound();
}

尝试1

enter image description here

尝试2

enter image description here

尝试3

MarTim的尝试通过了编译器,

public async Task<IActionResult> GetTodo(long id)
{
    return (IActionResult)(await _context.Todos.FindAsync(id)) ?? NotFound();
}

但会生成运行时错误:

enter image description here

2 个答案:

答案 0 :(得分:8)

让我们简化一下:

public async Task<ActionResult<Todo>> GetTodo(long id)
{
    Todo todo = await _context.Todos.FindAsync(id);
    return todo ?? NotFound();
}

这里的问题是todoNotFound()的类型非常不同。 todoTodo,但是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();