Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法将.NET泛型列表转换为其他泛型列表_C#_.net_Interface - Fatal编程技术网

C# 无法将.NET泛型列表转换为其他泛型列表

C# 无法将.NET泛型列表转换为其他泛型列表,c#,.net,interface,C#,.net,Interface,我正在尝试建立一个lastminute.com.auclone的模型。当我尝试创建一个IProductSearchServices集合时,我得到了所有关于(我猜)方差与协方差等奇怪的错误 我认为,如果任何具体类型实现了相同的接口,并且集合是强类型的,那么我可以使用任何具体类型(对于集合) 这是我要做的代码 private static void Main(string[] args) { // Expected: 3 services in this list. var prod

我正在尝试建立一个
lastminute.com.au
clone的模型。当我尝试创建一个
IProductSearchServices
集合时,我得到了所有关于(我猜)方差与协方差等奇怪的错误

我认为,如果任何具体类型实现了相同的接口,并且集合是强类型的,那么我可以使用任何具体类型(对于集合)

这是我要做的代码

private static void Main(string[] args)
{
    // Expected: 3 services in this list.
    var productServices = CreateProductServices();

    // Return all Hotel services.
    // Expected: 2 items in this list.
    var hotelServices = productServices.OfType<??????>();

    // for each hotel service, call SearchAsync.
    // wait for all the finish before continuing....

    Console.WriteLine("Found {0} products.", ....);
}

// Full code found in gist.... 
private static void Main(字符串[]args)
{
//预期:此列表中有3项服务。
var productServices=CreateProductServices();
//归还所有酒店服务。
//预期:此列表中有2项。
var hotelServices=productServices.OfType();
//对于每个酒店服务,请致电SearchAsync。
//在继续之前,等待所有的完成。。。。
WriteLine(“找到{0}个产品。”,…);
}
//在gist中找到完整代码。。。。
这是我的主要错误信息:

这是我的答案

那么问题是什么呢

  • 正在尝试向集合中添加3个搜索服务
  • 考虑到这个列表,我不知道如何说:给我所有的酒店服务,这样我就可以
    SearchAsync

  • 注意:我不想使用
    dynamic
    等。我想尝试将其作为强类型集合来使用。

    由于注释太有限,我将在回答中发布此内容。它可能无法解决您的问题,但我希望它能让您深入了解代码无法编译的原因。假设您具有以下结构:

    class Animal
    {
      public void Eat();
    }
    
    class Cow : Animal
    {
      public void Moo();
    }
    
    牛比动物重要。这意味着,在任何需要动物的地方,你也可以插上一头牛。然而,当预期会有一头母牛时,您不能插入动物,因为动物可能不是母牛,并且不知道如何鸣叫

    什么是协方差? 在没有差异的情况下,类型
    IEnumerable
    IEnumerable
    之间没有任何关联,但事实证明它们是相关的:在需要
    IEnumerable
    的地方,我们也可以插入
    IEnumerable
    。为什么呢?因为我们能用IEnumerable做的唯一一件事就是从中提取动物。这就是协方差的语法是
    out
    ,动物只通过
    IEnumerable
    返回的原因。我们刚刚得出结论,我们应该能够在任何地方使用奶牛而不是动物,因此,如果可计数的返回奶牛也可以。从这个意义上说,我们期望
    IEnumerable
    IEnumerable
    派生:我们应该能够在需要
    IEnumerable
    的地方插入
    IEnumerable
    。这就是协方差的作用

    什么是逆变? 类似地,在没有差异的情况下,
    Action
    Action
    类型不相关。和以前一样,事实证明是这样的,因为一种方法可以给一头奶牛。另一种情况是,通常情况下,取牛的方法不能给动物,因此在这种情况下,关系是另一种情况:
    Action
    应该是
    Action
    的子类型,因为取牛的方法也是取牛的方法,但是,一个方法,采取了一头牛,并不是一个方法,采取了一个动物:它可能想调用的牛穆奥,这是不可能的动物。在中,逆变的语法是
    ,因为逆变类型用作参数;他们不能归还

    首先,考虑一个更简单的版本<代码> iBufftSqcService < /C> >具有正确的方差:

    public interface IProductSearchService<out TProduct, in TSearchOptions>
      where TProduct : IProduct
      where TSearchOptions : ISearchOptions
    {
      TProduct SearchAsync(TSearchOptions searchOptions);
    }
    

    这里的问题之一是
    任务
    是一个类,而不是一个接口。协方差仅在接口上可用,因此,
    Task
    不能转换为
    Task
    。您可以通过使用而不是
    任务
    来解决这个问题,它是协变的,并提供类似的功能。另外,
    IList
    不是协变的,因此您可以使用
    IEnumerable
    来代替。然而,最大的问题是
    TSearchOptions
    ,这是一种反向变量。不能将
    ipProductSearchService
    分配给
    ipProductSearchService
    ,因为前者需要
    SearchAsync
    中更具体的参数,而不是不太具体的参数。因此,
    IPProductSearchService
    的列表是没有意义的。您好@RuudvA-感谢您的关注。不过,我不明白你在说什么:(我并不是说你错了-我只是不明白。我认为我的派生类
    HotelProductSearchService1
    是两个泛型,都是派生的。因此,如果两者都是派生的,那么它们都应该可以自动转换到它们的基础上?我很困惑。有代码可以帮助吗?其他人都已经提到了协方差等。我如果您需要在两种类型的列表之间进行转换,一种快速而肮脏的方法是使用“productServices.Cast()”哦,哇!这是一个非常棒的答案,我真的很想知道!好的-这-真的-帮助我现在理解了区别。呸!谢谢。所以我尝试了您所说的。但我仍然得到一个编译时错误。错误屏幕::~~(这是因为
    IList
    中的
    T
    是不可协变的。
    IList
    不是
    IList
    ,因为在
    IList
    上调用
    Add
    动物是不可能的。您必须使用
    IEnumerable
    。此外,必须仅获取属性。这也是因为
    out
    类型可以只能返回。在接口的实现中仍然可以有一个setter。我没有得到最后一个不起作用的位。正在尝试将2x hotels+1x flight service添加到集合中。集合是一个
    列表的列表,对我来说是一个
    列表
    ,所以..因此..我应该能够添加一个酒店(即奶牛)或航班(对我来说)收藏品只是说:我想收藏任何至少有一头奶牛的东西
    public interface IProductResult<out T> where T : IProduct { ... }
    
    public interface IProductSearchService<out TProduct, in TSearchOptions>
      where TProduct : IProduct
      where TSearchOptions : ISearchOptions
    {
      IObservable<IProductResult<TProduct>> SearchAsync(TSearchOptions searchOptions);
    }