我在尝试将一个实例转换为另一个实例类型时遇到问题。我认为,通过继承,这应该有效。
这是错误消息。 (对不起,这很难读 - 在新标签中打开它)
这是上下文。
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; }
}
所以我们有两个具体的类,它们都实现了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<..>
但这不起作用。这是...的错误消息..
答案 0 :(得分:2)
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;
}