提问人:Gopal Thakur 提问时间:11/10/2023 最后编辑:marc_sGopal Thakur 更新时间:11/11/2023 访问量:85
.NET Core 中的泛型 ActionResule<T> 不考虑类型 T
Generic ActionResule<T> in .NET Core doesnot respect the type T
问:
在下面的示例中,方法的返回类型为GET
ActionResult<SomeAltResult>
但是 return 语句返回 of 并且它仍然编译成功。OKResult
IEnumerable
WeatherForecast
我无法理解如果我可以返回任何东西,那么拥有泛型有什么意义,我可以使用或.ActionResult<T>
ActionResult
IActionResult
另外,请帮助我理解不继承任何类或接口链,那么多态性在这里是如何工作的?ActionResult<T>
OkObjectResult
namespace WebApplication1.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm","Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet(Name = "GetWeatherForecast")]
public ActionResult<SomeAltResult> Get()
{
var x = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
return Ok(x);
}
}
public class SomeAltResult
{
public string Name { get; set; }
}
答:
另外,请帮助我理解不继承任何类或接口链,那么多态性在这里是如何工作的?
ActionResult<T>
OkObjectResult
该类定义从任何 ActionResult 到 ActionResult<T>
的隐式转换,这解释了它编译的原因。
ActionResult<T>
像这样的代码还可以编译:
ActionResult<SomeAltResult> actionResult = Ok(x);
该转换很可能使用将任何 ActionResult
作为输入的构造函数重载。请注意,它不受泛型类型参数的任何约束。因此,您可以使用任何 ,包括 .ActionResult
OkObjectResult
我无法理解如果我可以返回任何东西,那么拥有泛型有什么意义,我可以使用或.
ActionResult<T>
ActionResult
IActionResult
这确实是一个奇怪的 API 设计。请考虑 OP 代码的以下变体:
ActionResult<SomeAltResult> actionResult = Ok(x);
SomeAltResult? value = actionResult.Value; // null
return Ok(value);
这也会编译,但 Web 资源现在返回一个空结果。发生这种情况是因为返回,因为它没有 类型的值。actionResult.Value
null
T
我无法解释 API 设计选择。这种无声的失败向我表明了 API 设计缺陷。像这样的代码不应该被允许在没有警告的情况下编译。
尽管如此,OP 仍能正常工作的原因是,ASP.NET 框架唯一关心的是控制器操作是否返回 IActionResult,而 ExecuteResultAsync 方法不关心泛型。它仅将对象隐藏为 HTTP 响应,并且在边界处不存在静态类型。IActionResult
评论