C# 如何在此场景中正确使用泛型和类型约束?
我对泛型和类型约束感到困惑,我将直截了当地说 我有一门BaseQueryResult课程C# 如何在此场景中正确使用泛型和类型约束?,c#,.net,generics,inheritance,.net-core,C#,.net,Generics,Inheritance,.net Core,我对泛型和类型约束感到困惑,我将直截了当地说 我有一门BaseQueryResult课程 public abstract class BaseQueryResult<T> { public int Count => Models != null && Models.Any() ? Models.Count : 0; public Exception Exception { get; set; } public bool HasExce
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; }
}
公共抽象类BaseQueryResult
{
public int Count=>Models!=null&&Models.Any()?Models.Count:0;
公共异常{get;set;}
公共bool HasException=>Exception!=null;
public bool issucess=>Exception==null;
公共布尔未找到{get;set;}
公共字符串ContinuationToken{get;set;}
公共IList模型{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);
}
}
公共类TransportListingQueryResult:BaseQueryResult
{
public TransportListingQueryResult(IList模型,字符串continuationToken)
{
模型=模型;
ContinuationToken=ContinuationToken;
NotFound=false;
}
公共交通列表查询结果(例外)
{
NotFound=false;
例外=例外;
}
public TransportListingQueryResult(布尔未找到,异常)
{
未找到=未找到;
例外=例外;
}
公共静态传输列表QueryResult NotFoundResult(异常)
{
返回新的TransportListingQueryResult(true,异常);
}
}
我正在使用的扩展方法
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);
}
}
}
公共静态类TransportListingQueryResultExtension
{
公共静态IActionResult到ActionResult(此T结果、控制器基础控制器、整数限制、字符串路由名称、对象值、HttpStatusCode successStatusCode=HttpStatusCode.OK)
其中T:BaseQueryResult
{
if(result.NotFound)
{
返回控制器.NotFound();
}
如果(!result.issucess)
{
if(result.HasException)
{
抛出结果异常;
}
返回controller.BadRequest(新的ErrorResponse{Messages=new[]{ErrorMessages.InternalServer}});
}
var uri=controller.Url.Link(路由名称,值);
var response=新的超媒体响应(
新链接项(uri),
新页面项(限制、result.ContinuationToken、result.Count),
结果(模型);
开关(成功状态代码)
{
案例HttpStatusCode。已创建:
返回控制器。已创建(string.Empty,response);
案例HttpStatusCode.OK:
违约:
返回控制器。Ok(响应);
}
}
}
最后是我在控制器中的动作
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);
}
公共异步任务创建([FromBody]CreateListingModel createListing)
{
var result=await_transportListingStore.CreateNewAsync(createListing);
返回result.ToActionResult(this,1,Constants.RouteNames.CreateListing,null,HttpStatusCode.Created);
}
我在这一行的操作中遇到了一个错误
返回result.ToActionResult
(
这
1.
Constants.RouteNames.CreateListing,
无效的
HttpStatusCode.Created
);
错误是:
类型“TransportListingQueryResult”不能用作泛型类型或方法“TransportListingQueryResultExtension.ToActionResult(T,ControllerBase,int,string,object,HttpStatusCode)”中的类型参数“T”。没有从“TransportListings.API.Application.Response.TransportListingQueryResult”到“TransportListings.API.Application.Response.BaseQueryResult”的隐式引用转换
我很困惑,因为我的子类继承了BaseQueryResult,但错误告诉我没有隐式引用转换。我不太确定我的代码出了什么问题,为什么它会给我错误
任何帮助都将不胜感激。提前感谢。问题是您的约束无法满足:
public static IActionResult ToActionResult<T>(this T result, /* snip */)
where T : BaseQueryResult<T>
publicstaticiactionresult到actionresult(这个T结果,/*snip*/)
其中T:BaseQueryResult
你真正想要的是:
public static IActionResult ToActionResult<T, U>(this T result, /* snip */)
where T : BaseQueryResult<U>
publicstaticiactionresult到actionresult(这个T结果,/*snip*/)
其中T:BaseQueryResult
这样称呼它:
return result.ToActionResult<TransportListingQueryResult, TransportListingQueryModel>(
this, /* snip */);
return result.ToActionResult(
这个,/*剪*/);
TransportListingQueryResult:BaseQueryResult
具有类型T
的TransportListingQueryModel
,您的扩展方法是result。ToActionResult
其中T
不是TransportListingQueryModel