有人可以解释一下为什么我在以下方法的null合并中出错:
private readonly Product[] products = new Product[];
[HttpGet("{id}")]
public ActionResult<Product> GetById(int id)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null)
return NotFound(); // No errors here
return product; // No errors here
//I want to replace the above code with this single line
return products.FirstOrDefault(p => p.Id == id) ?? NotFound(); // Getting an error here: Operator '??' cannot be applied to operands of type 'Product' and 'NotFoundResult'
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
我不明白的是为什么第一笔收益不需要任何强制转换而第二笔单行null合并无效!
我的目标是ASP.NET Core 2.1
编辑:
感谢@Hasan和@dcastro的解释,但我不建议您在此处使用null换行,因为NotFound()
在转换后将不会返回正确的错误代码!
return (ActionResult<Product>)products?.FirstOrDefault(p => p.Id == id) ?? NotFound();
答案 0 :(得分:1)
发生错误,因为无法转换类型。
尝试一下:
[HttpGet("{id}")]
public ActionResult<Product> GetById(int id)
{
var result = products?.FirstOrDefault(p => p.Id == id);
return result != null ? new ActionResult<Product>(result) : NotFound();
}
答案 1 :(得分:1)
[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id)
{
if (!_repository.TryGetProduct(id, out var product))
{
return NotFound();
}
return product;
}
在前面的代码中,当数据库中不存在该产品时,将返回404状态代码。如果产品确实存在,则 返回相应的Product对象。在ASP.NET Core 2.1之前, 退货;行本应返回Ok(product);。
从上面的代码和Microsoft相关page的解释中可以看出,在.NET Core 2.1之后,您无需像以前一样在控制器(ActionResult<T>
)中返回确切的类型。要使用该功能,您需要添加属性以指示可能的响应类型,例如[ProducesResponseType(200)]
等。
对于您而言,您需要做的基本上是向控制器方法中添加适当的响应类型属性,如下所示(因为您使用.NET Core 2.1进行开发)。
[HttpGet("{id}")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public ActionResult<Product> GetById(int id)
编辑:
之所以不能编译程序(使用null-coalescing运算符),是因为返回类型不具有竞争力。在一种情况下,它返回产品类别,否则返回ActionResult<T>
。按照我的建议更新代码后,我想您将可以使用null-coalescing运算符。
2。编辑 (在此处回答)
在深入研究问题之后,我发现当使用三元if语句或null合并运算符时,当可能返回多个类型时,我们需要明确指定期望从该语句生成的类型。如here之前的要求,编译器在不隐式转换的情况下不会决定返回哪种类型。因此,将返回类型强制转换为ActionResult即可解决问题。
return (ActionResult<Product>) products.FirstOrDefault(p=>p.id ==id) ?? NotFound();
但是最好如上所述添加响应类型属性。