【问题标题】:How to correctly use generics and type constraints in this scenario?在这种情况下如何正确使用泛型和类型约束?
【发布时间】:2018-04-27 01:34:53
【问题描述】:

我对泛型和类型约束感到困惑,我会直奔主题。

我有一个 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);
        }
    }
}

最后是我在控制器中的操作

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 );

错误是:

类型“TransportListings.API.Application.Response.TransportListingQueryResult”不能用作泛型类型或方法“TransportListingQueryResultExtension.ToActionResult(T, ControllerBase, int, string, object, HttpStatusCode)”中的类型参数“T”。没有从“TransportListings.API.Application.Response.TransportListingQueryResult”到“TransportListings.API.Application.Response.BaseQueryResult”的隐式引用转换

我很困惑,因为我的子类继承了 BaseQueryResult,但错误告诉我没有隐式引用转换。我不太确定我的代码出了什么问题,以及为什么它给了我这个错误。

任何帮助将不胜感激。提前致谢。

【问题讨论】:

  • TransportListingQueryResult : BaseQueryResult&lt;TransportListingQueryModel&gt; 的类型为 TTransportListingQueryModel 并且您的扩展方法是 result.ToActionResult&lt;TransportListingQueryResult&gt; 其中 T 不是 TransportListingQueryModel

标签: c# .net generics inheritance .net-core


【解决方案1】:

问题是你的约束不可能满足:

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 */);

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 2020-12-02
    • 2013-07-22
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多