2011-06-08 22 views
3

我有以下接口:可能通用的實現返回列表

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

我想有一些服務,可以返回的所有查詢的實現:

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

,然後能夠調用GetData on:

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

這是否可以用泛型來實現?

+0

你需要什麼類型的結果? – 2011-06-08 08:23:58

+0

@亨克這將取決於每個查詢實現 – adriaanp 2011-06-08 08:33:07

+0

恐怕不會。 – 2011-06-08 08:35:03

回答

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

0

您的IQueryProvider必須知道IQuery正在使用的泛型類型。我能想到的有兩種解決方案。

解決方案1:當您創建IQueryProvider實例

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

解決方案2定義泛型類型:傳入類型的方法

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

另外,我建議你查詢更改爲IQuery用於標準命名約定。

0

如果丟掉IList<>並將其替換爲IEnumerable<>,則可以使您的界面協變。不幸的是,沒有ReadOnlyList<>ReadOnlyCollection<>接口(不知道MS在那裏想什麼)。

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

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

請注意,這隻適用於參考類型TModel s。