c# - 需要一些帮助在两个 .NET 实例之间进行转换

标签 c# .net covariance contravariance

我在尝试将一个实例转换为另一种实例类型时遇到问题。我认为,通过继承,这应该可行。

这是错误消息。 (抱歉,它很难阅读 - 在新选项卡中打开它)

enter image description here

这是上下文。

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接口(interface)和一个包含 IItems 列表的结果类.

现在,我们如何使用它?我们定义一个搜索接口(interface)...

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<..>那是行不通的。这是错误消息..

enter image description here

最佳答案

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

关于c# - 需要一些帮助在两个 .NET 实例之间进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22444555/

相关文章:

.net - 哈希表/字典但键由多个值组成?

c# - 可以动态执行图像操作的图像 API/应用程序?

C++:如何在协变返回类型中重用代码?

kotlin - 当 contains() 接受 E 时,Kotlin 的 Set 如何是协变的?

scala - 为什么参数处于反位置?

c# - 从一组 n 中找出 K 个元素的所有变体

c# - 重定向到 Jquery 中的 Action-Controller MVC 4

c# - sql server 数据库中的审计记录更改

c# 当字符串数据超过 255 个字符时插入 Excel 时出错

c# - 当我尝试使用 ANTLR4 生成 C# 时出现的这些奇怪错误是什么?