铸造Templete内部价值问题
本文关键字:问题 内部 Templete 铸造 | 更新日期: 2023-09-27 18:20:54
我不能共享我的代码,但基本上我有一个类实现接口,如下所示:
public interface A
{
void doA();
}
public class B: A
{
public void doA()
{
// Doing A
}
}
我有一个类似的a的列表:
List<B> list = new List<B>();
list.Add(new B());
现在我想要一个IEnumerable<A>
。所以我试了这3行:
List<A> listCast = (List<A>)list;
IEnumerable<A> listCastToEnumerable = (IEnumerable<A>)list;
IEnumerable<A> listCastExt = list.Cast<A>();
- 第一个出现错误:
"错误1无法转换类型
'System.Collections.Generic.List<WindowsFormsApplication1.B>'
至'System.Collections.Generic.List<WindowsFormsApplication1.A>'
".
第二个没有得到错误,但得到了
InvalidCastException
。第三个成功了。
我的问题是:
- 为什么第一行出现错误,而第二行没有
- 为什么前两行无效
- 做这种演员的最好方法是什么?第三行有好处吗?或者有更好的方法吗
让我们将其分解。
1.
为什么第一行出现错误,而第二行没有?
在第二行中,您将转换为协变的IEnumerable(T)
。
2.
为什么前两行无效?
即使您铸造List<B>
,它仍然保留其基本类型信息,这意味着它不能保存不属于类型B的类型A的项目。
3.
做这种演员的最佳方式是什么?第三条线对此有好处吗?或者有更好的方法吗
第三行将List
的每个元素强制转换为类型A,并返回一个类型A的新IEnumerable(T)
。这可以迭代为类型A的一个新List
,它将愉快地容纳任何类型A的元素。
您也可以进行
IEnumerable<A> listoftypeb = list.OfType<A>();
如果您有一个元素不能键入
您需要创建一个IEnumerable(T)并用列表中的数据填充它,因为List<B>
不是IEnumerable<A>