我在尝试将一个实例转换为另一种实例类型时遇到麻烦。我认为通过继承,这应该可以工作。
这是错误消息。 (对不起,很难读-在新标签页中打开它)
这是上下文。
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;
}