如何将不同的具体实例(它们都继承了一个公共接口)添加到集合中

本文关键字:一个 集合 添加 接口 实例 继承 | 更新日期: 2023-09-27 17:58:27

我正在尝试向集合中添加一些具体实例,其中所有具体实例都继承自同一接口。但它不会编译。

// Common interface.
public interface ISearchService<in TSearchOptions> where TSearchOptions : ISearchOptions
{ .. }
// Concrete #1.
public class FooSearchService : ISearchService<FooSearchOptions>
{ .. }
// Concrete #2.
public class BaaSearchService : ISearchService<BaaSearchOptions>
{ .. }

因此,在上面的代码中,FooBaa都继承自ISearchService<ISearchOptions>,但每个都定义了自己特定的SearchOptions类型。

所以我尝试这个(不编译):

var searchServices = new List<ISearchService<ISearchOptions>>
{
    new FooSearchService(),
    new BaaSearchService()
};

我已经写了完整的代码。NET Fiddle。

这个想法是,我有一个共同的具体实例集合,它们都有一个公共的基本接口。

我很确定我在这方面的失败是因为我不理解的一些愚蠢的变化。

我想也许我想做的太多了。。所以我尝试了一个新的。NET摆弄一些不同的东西,但这也不起作用。

我只想要一个通用接口的混合包。

如何将不同的具体实例(它们都继承了一个公共接口)添加到集合中

您应该使用out而不是in:

out意味着covariant,这意味着参数可以从一个类更改为它的基类之一。想想方法的返回类型(输出),如果可以将方法的结果作为基类,则可以使用它的任何派生类。

in的意思是contravariant,这意味着参数可以从一个类更改为从它派生的类。想想方法的参数(输入),如果您的方法可以接受派生类,则可以传递给需要基类的方法。

public interface ISearchService<out T> where T : ISearchOptions
{  
}

注意:考虑方法的输入和输出只是我记住何时使用outin的策略,也是委托泛型类型参数的工作方式。基本上,covariantcontravariant对接口和委托的工作方式相同。

当您将代码更改为时,它会编译

public interface ISearchService<out TSearchOptions> where TSearchOptions : ISearchOptions
{  }