2016-07-24 58 views
0

我想添加一些具体实例到所有具体实例从同一个接口继承的集合中。但它不编译。如何将不同的具体实例(都继承一个通用接口)添加到集合中?

// 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

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

我敢肯定,我在这方面失败了,因为我常常只是不理解的一些*不一致的愚蠢。

我想也许我试图做太多..但是,这也行不通。

任何人都可以请帮忙吗?

我只想要一个共同的通用接口 :(

+0

我认为你的意思是“实现一个通用接口”。继承是一个类/子类的概念(搜索“实现”与“继承”)。最好使用适当的语言概念,以免混淆可能学习的其他读者。 –

回答

0

的鱼龙混杂,当你的代码更改为这它编译:

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

您应该使用out而不是in

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

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

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

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

+0

URGH :(你的答案一直工作......直到...我在界面中添加了以下方法:'Task SearchAsync(TSearchOptions searchOptions);'FML :( –

+0

@ Pure.Krome:'out'表示'输出',但你使用它作为输入是无效的:http://stackoverflow.com/questions/5041664/t-must-be-contravariantly-valid –

+0

所以没有办法做到这一点? –

相关问题