返回通用实现列表可能性

3

我有以下接口:

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

我希望有一种服务可以返回所有查询实现:

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

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

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

能否使用泛型来实现这个?

你想要 results 的什么类型? - H H
@Henk 这将取决于每个查询实现。 - adriaanp
3个回答

4

除了在 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的方法。


0

你的 IQueryProvider 必须知道 IQuery 正在使用哪种泛型类型。我能想到两个解决方案。

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

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

解决方法2:在方法中传入类型。
public interface IQueryProvider
{
    List<IQuery<TModel>> GetAllQueries<TModel>();
}

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


0

如果你将 IList<> 替换为 IEnumerable<>,你可以使你的接口协变。不幸的是,没有 ReadOnlyList<> 或者 ReadOnlyCollection<> 接口(不知道微软当时在想什么)。

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接