[問題] 泛型類別如何向下轉型?

作者: noodleT (麵T)   2017-10-04 14:08:04
class MyList<T>{}
interface IBase{}
interface ISub:IBase{}
如上,ISub 繼承 IBase ,令:
var a = new MyList<ISub>();
var b = (MyList<IBase>)a;
這時b強制轉型會造成錯誤。
我知道因為泛型會在執行階段
產生特殊版本來跑不同型別輸入,
因該是因為這原因讓編譯器認定
a,b 是兩種不同的型別,
但若有強制轉換需求該怎麼做?
作者: Litfal (Litfal)   2017-10-04 14:23:00
是要丟給別的method用?還是?用 a.Select(s=>(IBase)s).ToList() 另外建一個List比較簡單,不然你就要把MyList<T> 拉一個介面出來,然後寫成IMyList<out T>,不過會有一些問題你要自己摸索 XD因為你的MyList如果真的是個List,那麼會有in會有out,你不可能放進去不轉型拿出來也不轉型阿你可以把狗丟到動物園裡面,但動物園出來不一定是狗可以從狗屋裡面拿出一隻動物,但不能把任何動物丟進狗屋你想想你的問題,b=a; b.Add(base),base怎麼塞入a?一般來說,集合會用基底的類別或介面,然後再用多型直接用
作者: s4300026 (s4300026)   2017-10-05 07:54:00
為什麼不用內建的collection list這問題我當初的解法是list<base>,然後取出後is as轉想要的,就樓上的解法。
作者: CloudyWing (孤單ㄉ翼)   2017-10-07 15:46:00
泛型宣告T前面加out 讓他支援協變不過out要用到介面,所以要先訂一個interface給List實作
作者: noodleT (麵T)   2017-10-12 08:10:00
不用內建的是因為我要在 MyList 加入執行緒鎖。如果類別無法互相轉型,那只能分開放了。
作者: james732 (好人超)   2017-10-12 23:25:00
內建有執行緒安全的容器,不符合你的需求嗎?我同s4300026,會用is as來轉
作者: noodleT (麵T)   2017-10-12 23:37:00
因為我需要在整個 for each loop 都將資料陣列鎖住,避免其他人 add , remove所以原本內建集合沒辦法達到要求
作者: s4300026 (s4300026)   2017-10-17 20:34:00

Links booklink

Contact Us: admin [ a t ] ucptt.com