我在尝试将一个实例转换为另一种实例类型时遇到麻烦。我认为通过继承,这应该可以工作。

这是错误消息。 (对不起,很难读-在新标签页中打开它)



这是上下文。

public interface IItem { ... }

public class AuctionItem : IItem { ... }

public class BuyNowItem : IItem { ... }

public class SearchResult<T> where T : IItem
{
    public IList<T> Items { get; set; }
    public int TotalCount { get; set; }
}


因此,我们有2个具体的类,它们都实现了IItem接口和一个包含IItems列表的结果类。

现在,我们如何使用它?我们定义一个搜索界面...

public interface ISearchService<T, in TU>
    where T : IItem
    where TU : ISearchOptions
{
    string Name { get; }
    Task<SearchResult<T>> SearchAsync(TU searchOptions);
}


因此,在这里我们可以看到我们可以搜索某些内容(例如eBay),并且它将返回一些结果(例如IItems)。

我该如何实施?现在,我有一个看起来像这样的疯狂方法。

public class FooSearchService<T, TU> : ISearchService<T, TU>
    where T : AuctionItem, new()
    where TU : AuctionSearchOptions
{
    public async Task<SearchResult<T>> SearchAsync(TU searchOptions) { .. }
}


到目前为止似乎工作正常。

直到我现在尝试这个....

<my console app .. and yes, i'm not awaiting this call, etc...>
private SearchResult<IItem> DoSearches(Notification notification)
{
    if (ebay)
    {
        var searchResult = _ebaySearchService.SearchAsync(auctionSearchOptions);
        return searchResult.Result;  // ** COMPILE ERROR HERE
    }
    else if (somethingElse_eg_BuyNow_1)
    {
        ...
        return buyNowSearchResult.Result;
    }
}


看看我要做什么?我想说的是:搜索ebay并返回AuctionItem搜索结果。或者尝试其他服务并返回其BuyNowItem的...

我以为,因为ebay返回了SearchResult<AuctionItem>,所以调用方法想要返回SearchResut<IItem>实现的AuctionItem,所以我认为这没问题。但这不是:(

谁能提供帮助?

更新资料

现在几乎可以正常工作了:) @jdphenix的回答基本上使它可以工作。唯一的问题是我正在尝试返回一个Task<..>,但它不起作用。这是该错误消息。

最佳答案

public interface IItem { }

public class AuctionItem : IItem { }

public class BuyNowItem : IItem { }

public interface IResult<out T> where T : IItem {
  IList<IItem> Items { get; set; }
  int TotalCount { get; set; }
}

public class SearchResult<T> : IResult<T> where T : IItem
{
  public IList<IItem> Items { get; set; }
  public int TotalCount { get; set; }
}


您无法从SearchResult<AuctionItem>返回DoSearches(),因为这样做是可能的:

List<BuyNowItem> items = new List<SearchResult<BuyNowItem>>();
items.Add(DoSearches()); // Could be a SeachResult<AuctionItem>


接口IResult的作用是什么?


<out T>声明任何实现IResult的类型都将T作为输出。因此,您可以执行类似IResult<IItem> result = DoSearches()的操作,并且该操作有效。
IList<IItem>而不是IList<T>,因为编译器无法证明每个T都是对IItem的类型安全转换。对此的更全面的解释将需要比我更专业的人。


一个新的DoSearches()在概念上可以是这样的:

private IResult<IItem> DoSearches(Notification notification) {
  var searchresult = _ebaySearchService.SearchAsync(auctionSearchOptions);
  return searchresult;
}

10-07 16:48