如何将不同的具体实例(都继承了通用接口)添加到集合中?

时间:2016-07-24 02:42:18

标签: c# .net generics interface

我正在尝试将一些具体实例添加到集合中,其中所有具体实例都从相同的接口继承。但它没有编译。

// 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()
};

I've written the full code up on .NET Fiddle

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

我很确定我在这方面失败了,因为我常常不理解一些*差异愚蠢。

我想也许我想做太多.. so I've tried a new .NET Diffle with something different但这也行不通。

有人可以帮忙吗?

我只想要一个通用通用界面的混合包 :(

2 个答案:

答案 0 :(得分:1)

您应该使用out代替in

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

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

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

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

答案 1 :(得分:0)

当您将代码更改为此时编译:

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