返回通用实现列表

时间:2011-06-08 08:18:36

标签: c# .net generics

我有以下界面:

public interface Query<TModel>
{
    IList<TModel> GetData();
}

我想有一些可以返回所有查询实现的服务:

public interface IQueryProvider
{
   List<Query<>> GetAllQueries();
}

然后能够在一个上调用GetData:

var queries = provider.GetAllQueries();
var results = queries[0].GetData();

是否有可能通过泛型实现这一目标?

3 个答案:

答案 0 :(得分:4)

Query<>内部外,您无法使用开放式通用类型typeof()。如果要引用一组查询(未指定类型),则需要非泛型API,例如:

public interface IQuery {
     IList GetData();
     Type QueryType { get; }
}
public interface IQuery<TModel> : IQuery
{
    new IList<TModel> GetData();
}    
public interface IQueryProvider
{
   List<IQuery> GetAllQueries();
}
但是,这意味着你需要为每个人提供IQuery的影子实现,这很痛苦。请注意,如果任何服务同时实现IQuery<Foo>IQuery<Bar>,则上述内容也存在歧义 - 因为没有明显的方式来指示QueryType

答案 1 :(得分:0)

您的IQueryProvider必须知道IQuery使用的泛型类型。我能想到两种解决方案。

解决方案1:在创建IQueryProvider实例时定义泛型类型

public interface IQueryProvider<TModel>
{
    List<IQuery<TModel>> GetAllQueries();
}

解决方案2:传入方法中的类型

public interface IQueryProvider
{
    List<IQuery<TModel>> GetAllQueries<TModel>();
}

另外,我建议您将Query更改为IQuery以获得标准命名约定。

答案 2 :(得分:0)

如果您丢弃IList<>并将其替换为IEnumerable<>,则可以使您的界面协变。不幸的是,没有ReadOnlyList<>ReadOnlyCollection<>界面(不知道MS在那里想的是什么)。

public interface Query<out TModel>
{
    IEnumerable<TModel> GetData();
}

public interface IQueryProvider
{
   List<Query<object>> GetAllQueries();
}

请注意,这仅适用于引用类型TModel