[问题] 泛型类别如何向下转型?

楼主: 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