将隐含为派生类型较少的对象放入派生类型较多的列表中
本文关键字:类型 派生 列表 对象 | 更新日期: 2023-09-27 18:32:51
在这种情况下,我有一个派生类型较多的列表和另一个派生较少类型的列表。为了避免派生较少的列表出现任意混乱,我编写了一个 foreach 语句,用于检查列表中的每个元素是否属于派生较多的类型,如果是,则将其移动到派生较多的元素列表中。此处演示了这一点:
namespace Test
{
class Tester
{
static void Method()
{
List<A> ListA = new List<A>();
List<B> ListB = new List<B>();
//populate the lists
foreach (A a in ListA)
if (a.GetType().ToString()=="Test.B")
{
ListA.Remove(a);
ListB.Add(a);
}
//Do stuff with the lists
}
}
class A
{
//stuff in class A
}
class B : A
{
//stuff in class B
}
}
这给了我一个编译器错误,说 A 类型的对象不能隐式转换为类型 B,因为编译器不够聪明,无法意识到将被转换的 a 实例测试为类型 B 阳性,因此首先不应该进行转换。有没有办法规避这个问题?
有没有办法规避这个问题?
是的 - 你投了它:
foreach (A a in listA)
{
if (a.GetType().ToString() == "Test.B")
{
listA.Remove(a);
listB.Add((B) a);
}
}
这将编译,但它仍然会失败,因为您正在修改要迭代的集合。解决此问题的最简单方法是遍历列表的副本:
foreach (A a in listA.ToList())
根据您的要求,还有其他各种选择。
请注意,使用 is
或 as
比比较类型名称更干净。我还强烈建议您养成对所有foreach
语句使用大括号的习惯,即使是正文中只有一个语句的语句,并遵循局部变量的常见命名约定(例如listA
而不是ListA
(。
另请注意,这不是编译器"不够聪明"的问题 - 而是编译器遵循 C# 语言规范规则的问题。a
的编译时类型是A
- 就这么简单。碰巧在循环中的任何其他代码都不会更改该编译时类型,因此不会更改使用它的方式。
虽然偶尔这可能很烦人,但它使语言变得更加简单和可预测。如果以前的操作改变了过载解决的工作方式等,那将非常奇怪。