2012-05-25 20 views
6

我讀了一些關於泛型方差的內容,但我還沒有完全理解它,但是我想知道它是否會產生類似以下內容的內容?C#4.0的差異可以幫助我調用一個基礎類的構造函數與upcast?

class A<T> { } 

class B { } 

class C : B { } 

class My1 { 
    public My1(A<B> lessDerivedTemplateParameter) 
    { 
    } 
} 

class My2 : My1 { 
    public My2(A<C> moreDerivedTemplateParameter) 
     : base(moreDerivedTemplateParameter) // <-- compile error here, cannot convert 
    { 
    } 
} 
+1

我不那麼流利的泛型varian因爲這是一個評論,而不是一個答案,但我認爲你需要將'A '定義爲'A '來進行編譯。 – psubsee2003

+3

@ psubsee2003:我相信只能用於接口。 – Douglas

+0

有趣的是,我做了你的建議加上必須使A和界面,然後它編譯...我會繼續前進,看看我是否可以得到同樣的結果我以後,謝謝... –

回答

6

沒有,因爲在從BC繼承,A<C>不從A<B>繼承。

要理解爲什麼是這樣的話,想象一下,如果A<T>是不是List<T>

class B { } 

class C : B { } 

class D : B { } 

class My1 { 
    public My1(List<B> lessDerivedTemplateParameter) 
    { 
     // This is totally legal 
     lessDerivedTemplateParameter.Add(new D()); 
    } 
} 

class My2 : My1 { 
    public My2(List<C> moreDerivedTemplateParameter) 
     // if this were allowed, then My1 could add a D to a list of Bs 
     : base(moreDerivedTemplateParameter) 
    { 
    } 
} 

現在,在另一方面,這是合法的:

interface IA<out T> { 
    public T GetSome(); 
} 

class B { } 

class C : B { } 

class D : B { } 

class My1 { 
    public My1(IA<B> lessDerivedTemplateParameter) 
    { 
     // This is totally legal 
     var someB = lessDerivedTemplateParameter.GetSome(); 
    } 
} 

class My2 : My1 { 
    public My2(IA<C> moreDerivedTemplateParameter) 
     // This is allowed, because an A<C> only *produces* C's (which are also B's) 
     // so the base class (which consumes B's, and doesnt care if they are C's) 
     // can use an IA<C> 
     : base(moreDerivedTemplateParameter) 
    { 
    } 
} 
+0

這是正確的,但錯過了問題的重點。他*知道*目前的設置不起作用,並且想知道他是否可以利用差異來改變這種情況。你剛纔重申了他已經知道的東西。 – dlev

+0

@dlev我添加了一個插圖,說明*做什麼工作 –

+0

不錯。確實+1。 – dlev

2

可以聲明爲一個接口與一個逆變類型參數,它將編譯:

internal interface A<out T> 
    { 
    } 

    internal class B 
    { 
    } 

    internal class C : B 
    { 
    } 

    internal class My1 
    { 
    public My1(A<B> lessDerivedTemplateParameter) 
    { 
    } 
} 

internal class My2 : My1 
{ 
    public My2(A<C> moreDerivedTemplateParameter) 
     : base(moreDerivedTemplateParameter) 
    { 
    } 

} 
+1

這裏要注意的關鍵是這限制了A只生產(而不是消費)類型T. –

+0

@ChrisShain,這就是「out」權的含義的連接? –

+0

@AaronAnodide,這是正確的 –

相關問題