我对泛型和类型约束感到困惑,我将开门见山。
我有一个 BaseQueryResult 类
public abstract class BaseQueryResult<T>
{
public int Count => Models != null && Models.Any() ? Models.Count : 0;
public Exception Exception { get; set; }
public bool HasException => Exception != null;
public bool IsSuccess => Exception == null;
public bool NotFound { get; set; }
public string ContinuationToken { get; set; }
public IList<T> Models { get; set; }
}
从上面继承的子类
public class TransportListingQueryResult : BaseQueryResult<TransportListingQueryModel>
{
public TransportListingQueryResult(IList<TransportListingQueryModel> models, string continuationToken)
{
Models = models;
ContinuationToken = continuationToken;
NotFound = false;
}
public TransportListingQueryResult(Exception exception)
{
NotFound = false;
Exception = exception;
}
public TransportListingQueryResult(bool notFound, Exception exception)
{
NotFound = notFound;
Exception = exception;
}
public static TransportListingQueryResult NotFoundResult(Exception exception)
{
return new TransportListingQueryResult(true, exception);
}
}
我正在使用的扩展方法
public static class TransportListingQueryResultExtension
{
public static IActionResult ToActionResult<T>(this T result, ControllerBase controller, int limit, string routeName, object values, HttpStatusCode successStatusCode = HttpStatusCode.OK)
where T : BaseQueryResult<T>
{
if (result.NotFound)
{
return controller.NotFound();
}
if (!result.IsSuccess)
{
if (result.HasException)
{
throw result.Exception;
}
return controller.BadRequest(new ErrorResponse { Messages = new[] { ErrorMessages.InternalServer } });
}
var uri = controller.Url.Link(routeName, values);
var response = new HyperMediaResponse<T>(
new LinkItem(uri),
new PageItem(limit, result.ContinuationToken, result.Count),
result.Models);
switch (successStatusCode)
{
case HttpStatusCode.Created:
return controller.Created(string.Empty, response);
case HttpStatusCode.OK:
default:
return controller.Ok(response);
}
}
}
最后是 Controller 中的 Action
public async Task<IActionResult> Create([FromBody]CreateListingModel createListing)
{
var result = await _transportListingStore.CreateNewAsync(createListing);
return result.ToActionResult<TransportListingQueryResult>(this, 1, Constants.RouteNames.CreateListing, null, HttpStatusCode.Created);
}
我在操作中的这一行出现错误 返回结果.ToActionResult ( 这, 1、 常量.RouteNames.CreateListing, 无效的, HttpStatusCode.Created );
错误是:
The type 'TransportListings.API.Application.Response.TransportListingQueryResult' cannot be used as type parameter 'T' in the generic type or method 'TransportListingQueryResultExtension.ToActionResult(T, ControllerBase, int, string, object, HttpStatusCode)'. There is no implicit reference conversion from 'TransportListings.API.Application.Response.TransportListingQueryResult' to 'TransportListings.API.Application.Response.BaseQueryResult'
我很困惑,因为我的子类继承了 BaseQueryResult,但错误告诉我没有隐式引用转换。我不太确定我的代码有什么问题以及为什么会给我这个错误。
如有任何帮助,我们将不胜感激。提前致谢。
最佳答案
问题是你的约束不可能满足:
public static IActionResult ToActionResult<T>(this T result, /* snip */)
where T : BaseQueryResult<T>
你真正想要的是:
public static IActionResult ToActionResult<T, U>(this T result, /* snip */)
where T : BaseQueryResult<U>
然后这样调用它:
return result.ToActionResult<TransportListingQueryResult, TransportListingQueryModel>(
this, /* snip */);
关于c# - 在这种情况下如何正确使用泛型和类型约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50054002/