從泛型類中繼承


上面示例中的Farm<T>類以及本章前面介紹的其他幾個類都繼承自一個泛型類型。

在Farm<T>中,這個類型是一個接口IEnumerable<T>。

這里Farm<T>在T上提供的約束也會在IEnumerable<T>中使用的T上添加一個額外的約束。

這可以用於限制未約束的類型,但是需要遵循一些規則。

 

首先,如果某個類型在它所繼承的基類型中受到了約束,該類型就不能“解除約束”。

也就是說,類型T在所繼承的基類型中使用時,該類型必須受到至少與基類型相同的約束。

例如,下面的代碼是正確的

class SuperFarm<T>:Farm<T>

        where T:SuperCow

{

}

因為T在Farm<T>中被約束為Animal,把它約束為SuperCow,就是把T約束為這些值的一個子集,所以這段代碼可以正常運行。

但是,不會編譯下面的代碼

class SuperFarm<T>:Farm<T>

        where T:struct

{

}

可以肯定地說,提供給SuperFarm<T>的類型T不能轉換為可由Farm<T>使用的T,所以代碼不會編譯。

甚至約束為超集的情況也會出現相同的問題:

class SuperFarm<T>:Farm<T>

        where T:class   //類約束

{

}

即使SuperFarm<T>允許有像Animal這樣的類型,Farm<T>中也不允許有滿足類約束的其他類型。

否則編譯就會失敗。

這個規則適用於本章前面介紹的所有約束類型。

 

另外,如果繼承了一個泛型類型,就必須提供所有必須的類型信息。

這可以使用其他泛型類型參數的形式來提供,如上所述,也可以顯式提供。

這也適用於繼承了泛型類型的非泛型類。

例如:

public class Cards:List<Card>,ICloneable

{

}

這是可行的

 

但下面的代碼會失敗

public class Cards:List<T>,ICloneable

因為沒有提供T的信息,所以不能編譯

 

注意:

如果給泛型類型提供了參數,例如,上面的List<Card>,就可以把類型引用為"關閉"。

同樣,繼承List<T>,就是繼承一個"打開"的泛型類型。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM