2017-06-18 87 views
3

比方說,我們有這幾種:C#泛型鑄造型兒童向母公司

class A {} 
class B : A {} 

class X<T> {} 

爲什麼我們不能做到這一點?

X<A> var = new X<B>(); 

是否有任何解決方法可用?

[編輯] 我試圖用協方差,但失敗了,因爲我想訪問內部X是T型和C#的屬性在接口用T類型不允許:

interface IX<out T> { 
    T sth {set; get;} 
} 

class X<T>: IX<T> { 
    T sth { set; get; } 
} 

[編輯2] 我也試過,但它失敗:

class X<T> where T : A 
{ 
    public T sth { set; get; } 

    public static implicit operator X<T>(X<B> v) 
    { 
     return new X<T> 
     { 
      sth = v.sth, 
     }; 
    } 
} 

很奇怪的是,C#不允許鑄造的「某事」。

+1

在__ [編輯2] __,當你說'新X {...}',記住'T'可以與任何具體類型時,可以取代這運行。例如,如果'T'碰巧是'class Evil:A'類型的呢?然後,將類型爲'B'的'v.sth'分配到'Evil'類型的屬性中。但他們沒有兼容的類型。它們之間唯一的「關係」('B'和'Evil')是從'A'派生出來的。所以'B'不是'Evil',所以分配是非法的。由於分配對於一些「T」的替換是非法的,因此分配通常是非法的。 –

+0

@JeppeStigNielsen你說得對[編輯2] – HamedH

回答

1

的問題是,類不支持協變和逆變,只有接口:

class A { } 
class B : A { } 

class X<T> : P<T> { } 

interface P<out T> 
{ 
} 

... 

P<A> var = new X<B>(); 

Covariance and Contravariance FAQ

+1

值得指出的是,類不支持協變和逆變,這就是我們所使用的接口的原因。 – Deadzone

+0

我有A. – HamedH

1

你需要協方差(字out標記類型參數T):

interface IX<out T> {} 

這僅與接口類型(和委託類型)允許的。而類型B必須是一個引用類型(class像這裏一樣)。

然後,這是罰款:

IX<B> ixb = ...; 
IX<A> ok = new IX<B>(); 
+0

類型T的某些屬性,因爲我有A. – HamedH

+1

類型T的一些財產,我不知道我能跟着你,我不能使用協方差我不能使用協方差。如果一個屬性可以被設置,那麼不允許'out',因爲它會破壞事物。就像如果你有一個IList的''和___if___'的IList <>'可即使它擁有一個索引用'set'訪問協變,那麼你可以把這個列表作爲IList的'',叫它'animalList '。然後'animalList [0] = new Elephant();'將大象插入貓的列表中。你現在可以看到爲什麼具有'set'訪問器的'T'類型的屬性使得無法請求'T'中的協變。 (比較'IReadOnlyList '只有'get',沒有'set'。) –