作者noodleT (面)
看板C_Sharp
标题[问题] 泛型类别如何向下转型?
时间Wed Oct 4 14:08:04 2017
class MyList<T>{}
interface IBase{}
interface ISub:IBase{}
如上,ISub 继承 IBase ,令:
var a = new MyList<ISub>();
var b = (MyList<IBase>)a;
这时b强制转型会造成错误。
我知道因为泛型会在执行阶段
产生特殊版本来跑不同型别输入,
因该是因为这原因让编译器认定
a,b 是两种不同的型别,
但若有强制转换需求该怎麽做?
-----
Sent from JPTT on my HTC_U-1u.
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.255.216.59
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1507097286.A.66F.html
1F:→ Litfal: 是要丢给别的method用?还是?10/04 14:23
2F:→ Litfal: 用 a.Select(s=>(IBase)s).ToList() 另外建一个List比较10/04 14:23
3F:→ Litfal: 简单,不然你就要把MyList<T> 拉一个介面出来,然後写成10/04 14:26
4F:→ Litfal: IMyList<out T>,不过会有一些问题你要自己摸索 XD10/04 14:26
5F:→ Litfal: 因为你的MyList如果真的是个List,那麽会有in会有out,10/04 14:27
我想把
MyList<ISub> MyList<IBase>
放入 Dictionary<int, T > 去统一管理,
但 T 不论是宣告成什麽,
都无法储存。
※ 编辑: noodleT (111.255.216.59), 10/04/2017 14:56:11
6F:→ Litfal: 你不可能放进去不转型拿出来也不转型阿 10/04 15:32
7F:→ Litfal: 你可以把狗丢到动物园里面,但动物园出来不一定是狗 10/04 15:33
8F:→ Litfal: 可以从狗屋里面拿出一只动物,但不能把任何动物丢进狗屋 10/04 15:34
9F:→ Litfal: 你想想你的问题,b=a; b.Add(base),base怎麽塞入a? 10/04 15:36
10F:→ Litfal: 一般来说,集合会用基底的类别或介面,然後再用多型直接用 10/04 15:37
11F:推 s4300026: 为什麽不用内建的collection list 10/05 07:54
12F:推 s4300026: 这问题我当初的解法是list<base>,然後取出後is as转想 10/05 07:57
13F:→ s4300026: 要的,就楼上的解法。 10/05 07:57
14F:推 CloudyWing: 泛型宣告T前面加out 让他支援协变 10/07 15:46
15F:→ CloudyWing: 不过out要用到介面,所以要先订一个interface给List实 10/07 15:48
16F:→ CloudyWing: 作 10/07 15:48
17F:→ noodleT: 不用内建的是因为我要在 MyList 加入执行绪锁。如果类别 10/12 08:10
18F:→ noodleT: 无法互相转型,那只能分开放了。 10/12 08:10
19F:→ james732: 内建有执行绪安全的容器,不符合你的需求吗? 10/12 23:25
20F:→ james732: 我同s4300026,会用is as来转 10/12 23:25
21F:→ noodleT: 因为我需要在整个 for each loop 都将资料阵列锁住,避免 10/12 23:37
22F:→ noodleT: 其他人 add , remove 10/12 23:37
23F:→ noodleT: 所以原本内建集合没办法达到要求 10/12 23:39
24F:推 s4300026: 应该没帮助,但加减看XD 10/17 20:34