2011-02-18 41 views
31

這是什麼問題?T必須是衝突有效

interface IRepository<out T> where T : IBusinessEntity 
{ 
    IQueryable<T> GetAll(); 
    void Save(T t); 
    void Delete(T t); 
} 

它說:

無效方差:類型參數 'T' 必須是 'MyNamespace.IRepository.Delete(T)' contravariantly有效。 'T'是協變的。

+1

你最終做了什麼?我面臨同樣的問題。答案並不能真正解決問題。我需要GetAll,Save和Delete在同一類 – David 2015-08-07 08:51:05

+1

對不起,我不記得了。那是4年前。 – Eduardo 2015-08-07 19:35:24

回答

55

考慮會發生什麼,如果編譯器允許的是:

interface IR<out T> 
{ 
    void D(T t); 
} 

class C : IR<Mammal> 
{ 
    public void D(Mammal m) 
    { 
     m.GrowHair(); 
    } 
} 
... 
IR<Animal> x = new C(); 
// legal because T is covariant and Mammal is convertible to Animal 
x.D(new Fish()); // legal because IR<Animal>.D takes an Animal 

而你只是試圖在一條魚長出頭髮。

「out」表示「T僅用於輸出位置」。您正在使用它在輸入位置。

19

以下兩種方法都是錯誤的:

void Save(T t); 
void Delete(T t); 

你不能有T作爲方法參數。只有在您的泛型定義中希望它是協變(out T)時才作爲返回類型。

或者,如果你想逆變那麼你可以使用泛型參數只能作爲方法的參數,而不是返回類型:

interface IRepository<in T> where T : IBusinessEntity 
{ 
    void Save(T t); 
    void Delete(T t); 
} 
+0

完整且乾淨的答案。謝謝 – 2012-01-28 17:42:19

37

您可以使用out型參數僅contravariantly,即在返回類型。因此,IQueryable<T> GetAll()是正確的,但void Delete(T t)不正確。

由於T在您的班級中同時使用,所以在這裏不能使用out(或in)。

這裏有一些背景:Covariance and Contravariance (Wikipedia)

+10

請注意,它*可以*在參數中,但只有像'Action `這樣的東西可以再次反轉方向。 – 2011-02-18 13:21:11

相關問題