返回可能的泛型实现的列表

本文关键字:实现 列表 泛型 返回 | 更新日期: 2023-09-27 17:58:34

我有以下接口:

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

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

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

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

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

有可能用泛型实现这一点吗?

返回可能的泛型实现的列表

除了在typeof()内部,不能使用开放泛型类型Query<>。如果您想引用一组查询(类型未指定),则需要一个非通用的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

如果抛出IList<>并将其替换为IEnumerable<>,则可以使接口协变。不幸的是,没有ReadOnlyList<>ReadOnlyCollection<>接口(不知道MS在想什么)。

public interface Query<out TModel>
{
    IEnumerable<TModel> GetData();
}
public interface IQueryProvider
{
   List<Query<object>> GetAllQueries();
}

请注意,这只适用于参考类型TModel s。

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

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

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

解决方案2:在方法中传递类型

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

此外,我建议您将Query更改为IQuery以实现标准命名约定。