2015-07-22 56 views
0

我有兩個類。我希望其中的一個接受兩個代表模型類型的參數,以及結果的類型。類型約束被解釋奇怪

我已經通過使用類型約束來表示TResult必須是TModelIEnumerable<TModel>。到現在爲止還挺好。現在,爲了避免每次都需要提供兩個類型參數,我想創建一個僅使用一個類型參數的第二個類,並且同時使用提供的兩個類型參數來繼承另一個類。這些類如下所示:

public class QueryBase<TResult, TModel> 
    where TModel : ModelBase 
    where TResult : TModel, IEnumerable<TModel> 
{ 

} 

public class QueryBase<TModel> : QueryBase<TModel, TModel> 
    where TModel : ModelBase 
{ 

} 

的問題是,當我嘗試這樣做,我得到從Visual Studio中的錯誤說以下內容:

類型「TResult」不能用作類型通用類型或方法'VTDI.Queries.QueryBase'中的參數'TResult'在 中。 沒有從'TResult'到 'TModel'的裝箱轉換或類型參數轉換。

我的問題是:這裏怎麼了?我原以爲我的類型約束可以保證轉換是可能的,但Visual Studio似乎並不同意。

+0

'其中TResult:TModel的,IEnumerable的'這意味着'TResult'必須'TModel' **和**的'的IEnumerable '。 – PetSerAl

+0

@PetSerAl你是對的,在這種情況下,我想知道爲什麼類型約束本身被接受爲有效的,因爲它是矛盾的,對嗎? –

+0

您不能將一個類型參數約束爲一個或另一個。如果你編寫了一個訪問'TModel'屬性的方法,那麼編譯器將如何知道你的類是什麼? – Blorgbeard

回答

1

這個限制實際上意味着TResult必須來自TModelIEnumerable<TModel>

where TResult : TModel, IEnumerable<TModel> 

問題出在第二類QueryBase<TModel>。其中對所述第二類型的約束僅僅是:

where TModel : ModelBase 

這種約束是比在基類QueryBase<TResult, TModel>所述一個限制較少。

where TResult : TModel, IEnumerable<TModel> 

如果更改了限制第二類是限制性的頭等艙,那麼你將能夠編譯:

public class QueryBase<TModel> : QueryBase<TModel, TModel> 
    where TModel : ModelBase, IEnumerable<TModel> 

但我懷疑這是T優真想做。看起來你可能會遺傳你的遺傳。你可以通過使QueryBase<TModel>作爲基類來完成你正在試圖做的事情,然後使QueryBase<TResult, TModel>繼承嗎?

1
public class QueryBase<TModel> : QueryBase<TModel, TModel> 
    where TModel : ModelBase 

通過類型參數代入超類型你:

public class QueryBase 
    where (TModel : ModelBase) => (TModel : ModelBase) 
    where (TModel : ModelBase) => (TModel : TModel, IEnumerable<TModel>) 

我捏造的語法,使點。用x => y我的意思是y必須遵循假設x。問題是你不能從TModel : ModelBase得出TModel : IEnumerable<TModel>。一個可能的解決方法是將此約束添加到子類型。

public class QueryBase<TModel> : QueryBase<TModel, TModel> 
    where TModel : ModelBase, IEnumerable<TModel>