Domanda

I'm having trouble trying to convert one instance to another instance type. I thought, via inheritence, that this should just work.

Here's the error message. (sorry it's hard to read - open it in a new tab)

enter image description here

And here's the context.

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

So we have 2 concrete classes, which both implement the IItem interface and a result class which contains a list of IItems.

Now, how do we use this? We define a searching interface...

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

So here we can see that we can search something (eg. eBay) and it will return some results (eg IItems).

How do I implement this? Now, I have a crazy method that looks like this....

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

Seems to be working fine so far ....

Until i now try this ....

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

See what I'm trying to do? I'm trying to say: Search ebay and return the AuctionItem search results. Or try another service and return their BuyNowItem's ...

I thought that, because the ebay returns a SearchResult<AuctionItem>, the calling method wants to return a SearchResut<IItem> which AuctionItem implements, so I assumed it would be ok. But it's not :(

Can anyone offer any assistance?

Update

Nearly got it all working now :) The answer from @jdphenix basically made it work. The only problem is that I'm trying to return a Task<..> and that's not working. Here's the error message for that..

enter image description here

È stato utile?

Soluzione

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

You are unable to return a SearchResult<AuctionItem> from DoSearches() because then this would be possible:

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

What does the interface IResult do?

  • <out T> declares that any type implementing IResult will have T as an output. Consequently, you can do something like IResult<IItem> result = DoSearches() and it be valid.
  • IList<IItem> instead of IList<T> because the compiler can't prove that every T would be a type safe conversion to IItem. The fuller explanation of this would require someone which much more expertise than me.

A new DoSearches() could conceptually be this:

private IResult<IItem> DoSearches(Notification notification) {
  var searchresult = _ebaySearchService.SearchAsync(auctionSearchOptions);
  return searchresult;
} 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top